set(common_SRCS
content_tool.cpp
- tool.cpp
- mapnode_contentfeatures.cpp
+ tooldef.cpp
+ nodedef.cpp
luaentity_common.cpp
scriptapi.cpp
script.cpp
#include <cmath>
#include <SAnimatedMesh.h>
#include "settings.h"
-#include "mapnode_contentfeatures.h" // For wield visualization
+#include "nodedef.h" // For wield visualization
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr),
m_wanted_frametime = 1.0 / wanted_fps;
}
-void Camera::wield(const InventoryItem* item, ITextureSource *tsrc)
+void Camera::wield(const InventoryItem* item, IGameDef *gamedef)
{
+ ITextureSource *tsrc = gamedef->tsrc();
+ INodeDefManager *ndef = gamedef->ndef();
+
if (item != NULL)
{
bool isCube = false;
// A block-type material
MaterialItem* mat_item = (MaterialItem*) item;
content_t content = mat_item->getMaterial();
- if (content_features(content).solidness || content_features(content).visual_solidness)
+ if (ndef->get(content).solidness || ndef->get(content).visual_solidness)
{
- m_wieldnode->setCube(content_features(content).tiles);
+ m_wieldnode->setCube(ndef->get(content).tiles);
m_wieldnode->setScale(v3f(30));
isCube = true;
}
class LocalPlayer;
class MapDrawControl;
class ExtrudedSpriteSceneNode;
-class ITextureSource;
+class IGameDef;
/*
Client camera class, manages the player and camera scene nodes, the viewing distance
void updateSettings();
// Replace the wielded item mesh
- void wield(const InventoryItem* item, ITextureSource *tsrc);
+ void wield(const InventoryItem* item, IGameDef *gamedef);
// Start digging animation
// Pass 0 for left click, 1 for right click
#include "profiler.h"
#include "log.h"
#include "nodemetadata.h"
+#include "nodedef.h"
+#include "tooldef.h"
/*
QueuedMeshUpdate
ScopeProfiler sp(g_profiler, "Client: Mesh making");
scene::SMesh *mesh_new = NULL;
- mesh_new = makeMapBlockMesh(q->data, m_tsrc);
+ mesh_new = makeMapBlockMesh(q->data, m_gamedef);
MeshUpdateResult r;
r.p = q->p;
const char *playername,
std::string password,
MapDrawControl &control,
- ITextureSource *tsrc,
- IToolDefManager *toolmgr):
+ IWritableTextureSource *tsrc,
+ IWritableToolDefManager *tooldef,
+ IWritableNodeDefManager *nodedef
+):
m_tsrc(tsrc),
- m_toolmgr(toolmgr),
- m_mesh_update_thread(tsrc),
+ m_tooldef(tooldef),
+ m_nodedef(nodedef),
+ m_mesh_update_thread(this),
m_env(
new ClientMap(this, this, control,
device->getSceneManager()->getRootSceneNode(),
m_playerpos_send_timer = 0.0;
m_ignore_damage_timer = 0.0;
- //m_env_mutex.Init();
- //m_con_mutex.Init();
+ // Build main texture atlas, now that the GameDef exists (that is, us)
+ if(g_settings->getBool("enable_texture_atlas"))
+ tsrc->buildMainAtlas(this);
+ else
+ infostream<<"Not building texture atlas."<<std::endl;
+ // NOTE: This should be done only after getting possible dynamic
+ // game definitions from the server, or at least shut down and
+ // restarted when doing so
m_mesh_update_thread.Start();
/*
Add local player
*/
{
- //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
- Player *player = new LocalPlayer();
+ Player *player = new LocalPlayer(this);
player->updateName(playername);
//TimeTaker t1("TOCLIENT_ADDNODE");
MapNode n;
- n.deSerialize(&data[8], ser_version);
+ n.deSerialize(&data[8], ser_version, m_nodedef);
addNode(p, n);
}
Update an existing block
*/
//infostream<<"Updating"<<std::endl;
- block->deSerialize(istr, ser_version, this);
+ block->deSerialize(istr, ser_version);
}
else
{
Create a new block
*/
//infostream<<"Creating new"<<std::endl;
- block = new MapBlock(&m_env.getMap(), p);
- block->deSerialize(istr, ser_version, this);
+ block = new MapBlock(&m_env.getMap(), p, this);
+ block->deSerialize(istr, ser_version);
sector->insertBlock(block);
//DEBUG
// Create a player if it doesn't exist
if(player == NULL)
{
- player = new RemotePlayer(
+ player = new RemotePlayer(this,
m_device->getSceneManager()->getRootSceneNode(),
m_device,
-1);
i = affected_blocks.getIterator();
i.atEnd() == false; i++)
{
- i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio(), m_tsrc);
+ i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
}
}
i = affected_blocks.getIterator();
i.atEnd() == false; i++)
{
- i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio(), m_tsrc);
+ i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
}
}
}
}
+// IGameDef interface
+// Under envlock
+IToolDefManager* Client::getToolDefManager()
+{
+ return m_tooldef;
+}
+INodeDefManager* Client::getNodeDefManager()
+{
+ return m_nodedef;
+}
+ITextureSource* Client::getTextureSource()
+{
+ return m_tsrc;
+}
+
#include "gamedef.h"
struct MeshMakeData;
+class IGameDef;
+class IWritableToolDefManager;
+class IWritableNodeDefManager;
class ClientNotReadyException : public BaseException
{
{
public:
- MeshUpdateThread(ITextureSource *tsrc):
- m_tsrc(tsrc)
+ MeshUpdateThread(IGameDef *gamedef):
+ m_gamedef(gamedef)
{
}
MutexedQueue<MeshUpdateResult> m_queue_out;
- ITextureSource *m_tsrc;
+ IGameDef *m_gamedef;
};
enum ClientEventType
const char *playername,
std::string password,
MapDrawControl &control,
- ITextureSource *tsrc,
- IToolDefManager *toolmgr
+ IWritableTextureSource *tsrc,
+ IWritableToolDefManager *tooldef,
+ IWritableNodeDefManager *nodedef
);
~Client();
// IGameDef interface
// Under envlock
- virtual IToolDefManager* getToolDefManager()
- { return m_toolmgr; }
- virtual INodeDefManager* getNodeDefManager()
- { assert(0); return NULL; } // TODO
+ virtual IToolDefManager* getToolDefManager();
+ virtual INodeDefManager* getNodeDefManager();
+ virtual ITextureSource* getTextureSource();
private:
float m_ignore_damage_timer; // Used after server moves player
IntervalLimiter m_map_timer_and_unload_interval;
- ITextureSource *m_tsrc;
- IToolDefManager *m_toolmgr;
+ IWritableTextureSource *m_tsrc;
+ IWritableToolDefManager *m_tooldef;
+ IWritableNodeDefManager *m_nodedef;
MeshUpdateThread m_mesh_update_thread;
ClientEnvironment m_env;
con::Connection m_con;
#include "collision.h"
#include "mapblock.h"
#include "map.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
-collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f)
{
collisionMoveResult result;
try{
// Object collides into walkable nodes
MapNode n = map->getNode(v3s16(x,y,z));
- if(content_features(n).walkable == false)
+ if(gamedef->getNodeDefManager()->get(n).walkable == false)
continue;
}
catch(InvalidPositionException &e)
return result;
}
-collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f)
{
collisionMoveResult final_result;
dtime_downcount = 0;
}
- collisionMoveResult result = collisionMoveSimple(map, pos_max_d,
- box_0, dtime_part, pos_f, speed_f);
+ collisionMoveResult result = collisionMoveSimple(map, gamedef,
+ pos_max_d, box_0, dtime_part, pos_f, speed_f);
if(result.touching_ground)
final_result.touching_ground = true;
#include "common_irrlicht.h"
class Map;
+class IGameDef;
struct collisionMoveResult
{
};
// Moves using a single iteration; speed should not exceed pos_max_d/dtime
-collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f);
// Moves using as many iterations as needed
-collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f);
enum CollisionType
#include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor()
#include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
#ifndef SERVER
// Create a cuboid.
#ifndef SERVER
void mapblock_mesh_generate_special(MeshMakeData *data,
- MeshCollector &collector, ITextureSource *tsrc)
+ MeshCollector &collector, IGameDef *gamedef)
{
+ ITextureSource *tsrc = gamedef->tsrc();
+ INodeDefManager *nodedef = gamedef->ndef();
+
// 0ms
//TimeTaker timer("mapblock_mesh_generate_special()");
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0, ap.atlas);
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16;
/*
Add flowing liquid to mesh
*/
- else if(content_features(n).liquid_type == LIQUID_FLOWING)
+ else if(nodedef->get(n).liquid_type == LIQUID_FLOWING)
{
- assert(content_features(n).special_material);
+ assert(nodedef->get(n).special_material);
video::SMaterial &liquid_material =
- *content_features(n).special_material;
+ *nodedef->get(n).special_material;
video::SMaterial &liquid_material_bfculled =
- *content_features(n).special_material2;
+ *nodedef->get(n).special_material2;
- assert(content_features(n).special_atlas);
+ assert(nodedef->get(n).special_atlas);
AtlasPointer &pa_liquid1 =
- *content_features(n).special_atlas;
+ *nodedef->get(n).special_atlas;
bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
- content_t c_flowing = content_features(n).liquid_alternative_flowing;
- content_t c_source = content_features(n).liquid_alternative_source;
+ content_t c_flowing = nodedef->get(n).liquid_alternative_flowing;
+ content_t c_source = nodedef->get(n).liquid_alternative_source;
if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
top_is_same_liquid = true;
u8 l = 0;
// Use the light of the node on top if possible
- if(content_features(ntop).param_type == CPT_LIGHT)
- l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
+ if(nodedef->get(ntop).param_type == CPT_LIGHT)
+ l = decode_light(ntop.getLightBlend(data->m_daynight_ratio, nodedef));
// Otherwise use the light of this node (the liquid)
else
- l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(
- content_features(n).vertex_alpha, l);
+ nodedef->get(n).vertex_alpha, l);
// Neighbor liquid levels (key = relative position)
// Includes current node
continue;
content_t neighbor_content = neighbor_contents[dir];
- ContentFeatures &n_feat = content_features(neighbor_content);
+ const ContentFeatures &n_feat = nodedef->get(neighbor_content);
// Don't draw face if neighbor is blocking the view
if(n_feat.solidness == 2)
/*
Add water sources to mesh if using new style
*/
- else if(content_features(n).liquid_type == LIQUID_SOURCE
+ else if(nodedef->get(n).liquid_type == LIQUID_SOURCE
&& new_style_water)
{
- assert(content_features(n).special_material);
+ assert(nodedef->get(n).special_material);
video::SMaterial &liquid_material =
- *content_features(n).special_material;
- assert(content_features(n).special_atlas);
+ *nodedef->get(n).special_material;
+ assert(nodedef->get(n).special_atlas);
AtlasPointer &pa_liquid1 =
- *content_features(n).special_atlas;
+ *nodedef->get(n).special_atlas;
bool top_is_air = false;
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
if(top_is_air == false)
continue;
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(
- content_features(n).vertex_alpha, l);
+ nodedef->get(n).vertex_alpha, l);
video::S3DVertex vertices[4] =
{
*/
else if(n.getContent() == CONTENT_LEAVES && new_style_leaves)
{
- /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));*/
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));*/
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++)
*/
else if(n.getContent() == CONTENT_GLASS)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++)
*/
else if(n.getContent() == CONTENT_FENCE)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
const f32 post_rad=(f32)BS/10;
/*
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++)
{
v3s16 dir = g_6dirs[j];
/*u8 l = 0;
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir);
- if(content_features(n2).param_type == CPT_LIGHT)
- l = decode_light(n2.getLightBlend(data->m_daynight_ratio));
+ if(nodedef->get(n2).param_type == CPT_LIGHT)
+ l = decode_light(n2.getLightBlend(data->m_daynight_ratio, nodedef));
else
l = 255;*/
u8 l = 255;
video::SColor c = MapBlock_LightColor(255, l);
// Get the right texture
- TileSpec ts = n.getTile(dir, tsrc);
+ TileSpec ts = n.getTile(dir, tsrc, nodedef);
AtlasPointer ap = ts.texture;
material_general.setTexture(0, ap.atlas);
#endif
else if(n.getContent() == CONTENT_PAPYRUS)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
}
else if(n.getContent() == CONTENT_JUNGLEGRASS)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_rail.setTexture(0, ap.atlas);
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16;
material_ladder.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_ladder.setTexture(0, ap.atlas);
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c(255,l,l,l);
float d = (float)BS/16;
}
else if(n.getContent() == CONTENT_APPLE)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
}
}
else if(n.getContent() == CONTENT_SAPLING) {
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
#ifndef SERVER
#include "mapblock_mesh.h"
#include "utility.h"
-class ITextureSource;
+class IGameDef;
void mapblock_mesh_generate_special(MeshMakeData *data,
- MeshCollector &collector, ITextureSource *tsrc);
+ MeshCollector &collector, IGameDef *gamedef);
#endif
#endif
#include "mapnode.h"
#include "content_nodemeta.h"
#include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#define WATER_ALPHA 160
}
// See header for description
-void content_mapnode_init(ITextureSource *tsrc)
+void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr)
{
if(tsrc == NULL)
dstream<<"INFO: Initial run of content_mapnode_init with "
ContentFeatures *f = NULL;
i = CONTENT_STONE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "stone.png");
f->setInventoryTextureCube("stone.png", "stone.png", "stone.png", tsrc);
f->param_type = CPT_MINERAL;
f->solidness = 0; // For debugging, hides regular stone
i = CONTENT_GRASS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png^grass_side.png");
f->setTexture(tsrc, 0, "grass.png");
f->setTexture(tsrc, 1, "mud.png");
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_GRASS_FOOTSTEPS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png^grass_side.png");
f->setTexture(tsrc, 0, "grass_footsteps.png");
f->setTexture(tsrc, 1, "mud.png");
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_MUD;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png");
f->setInventoryTextureCube("mud.png", "mud.png", "mud.png", tsrc);
f->param_type = CPT_MINERAL;
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_SAND;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "sand.png");
f->setInventoryTextureCube("sand.png", "sand.png", "sand.png", tsrc);
f->param_type = CPT_MINERAL;
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_GRAVEL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "gravel.png");
f->setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png", tsrc);
f->param_type = CPT_MINERAL;
setGravelLikeMaterialProperties(f->material, 1.0);
i = CONTENT_SANDSTONE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "sandstone.png");
f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png", tsrc);
f->param_type = CPT_MINERAL;
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_CLAY;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "clay.png");
f->setInventoryTextureCube("clay.png", "clay.png", "clay.png", tsrc);
f->param_type = CPT_MINERAL;
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_BRICK;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "brick.png");
f->setInventoryTextureCube("brick.png", "brick.png", "brick.png", tsrc);
f->param_type = CPT_MINERAL;
setStoneLikeMaterialProperties(f->material, 1.0);
i = CONTENT_TREE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "tree.png");
f->setTexture(tsrc, 0, "tree_top.png");
f->setTexture(tsrc, 1, "tree_top.png");
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_JUNGLETREE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "jungletree.png");
f->setTexture(tsrc, 0, "jungletree_top.png");
f->setTexture(tsrc, 1, "jungletree_top.png");
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_JUNGLEGRASS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("junglegrass.png", tsrc);
- f->used_texturenames["junglegrass.png"] = true;
+ f->used_texturenames.insert("junglegrass.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
//f->is_ground_content = true;
setLeavesLikeMaterialProperties(f->material, 1.0);
i = CONTENT_LEAVES;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->light_propagates = true;
//f->param_type = CPT_MINERAL;
f->param_type = CPT_LIGHT;
setLeavesLikeMaterialProperties(f->material, 1.0);
i = CONTENT_CACTUS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cactus_side.png");
f->setTexture(tsrc, 0, "cactus_top.png");
f->setTexture(tsrc, 1, "cactus_top.png");
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_PAPYRUS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("papyrus.png", tsrc);
- f->used_texturenames["papyrus.png"] = true;
+ f->used_texturenames.insert("papyrus.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
setLeavesLikeMaterialProperties(f->material, 0.5);
i = CONTENT_BOOKSHELF;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "bookshelf.png");
f->setTexture(tsrc, 0, "wood.png");
f->setTexture(tsrc, 1, "wood.png");
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_GLASS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->light_propagates = true;
f->sunlight_propagates = true;
f->param_type = CPT_LIGHT;
setGlassLikeMaterialProperties(f->material, 1.0);
i = CONTENT_FENCE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
f->solidness = 0; // drawn separately, makes no faces
f->air_equivalent = true; // grass grows underneath
f->setInventoryTexture("fence.png", tsrc);
- f->used_texturenames["fence.png"] = true;
+ f->used_texturenames.insert("fence.png"); // Add to atlas
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_RAIL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("rail.png", tsrc);
- f->used_texturenames["rail.png"] = true;
+ f->used_texturenames.insert("rail.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
setDirtLikeMaterialProperties(f->material, 0.75);
i = CONTENT_LADDER;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("ladder.png", tsrc);
- f->used_texturenames["ladder.png"] = true;
+ f->used_texturenames.insert("ladder.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
// Deprecated
i = CONTENT_COALSTONE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "stone.png^mineral_coal.png");
f->is_ground_content = true;
setStoneLikeMaterialProperties(f->material, 1.5);
i = CONTENT_WOOD;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "wood.png");
f->setInventoryTextureCube("wood.png", "wood.png", "wood.png", tsrc);
f->is_ground_content = true;
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_MESE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mese.png");
f->setInventoryTextureCube("mese.png", "mese.png", "mese.png", tsrc);
f->is_ground_content = true;
setStoneLikeMaterialProperties(f->material, 0.5);
i = CONTENT_CLOUD;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cloud.png");
f->setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png", tsrc);
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
i = CONTENT_AIR;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
f->air_equivalent = true;
i = CONTENT_WATER;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
f->param_type = CPT_LIGHT;
f->light_propagates = true;
#endif
i = CONTENT_WATERSOURCE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
//f->setInventoryTexture("water.png", tsrc);
f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
if(new_style_water)
#endif
i = CONTENT_LAVA;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc);
- f->used_texturenames["lava.png"] = true;
+ f->used_texturenames.insert("lava.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = false;
f->light_source = LIGHT_MAX-1;
#endif
i = CONTENT_LAVASOURCE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc);
- f->used_texturenames["ladder.png"] = true;
+ f->used_texturenames.insert("ladder.png"); // Add to atlas
if(new_style_water)
{
f->solidness = 0; // drawn separately, makes no faces
#endif
i = CONTENT_TORCH;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("torch_on_floor.png", tsrc);
- f->used_texturenames["torch_on_floor.png"] = true;
- f->used_texturenames["torch_on_ceiling.png"] = true;
- f->used_texturenames["torch_on_floor.png"] = true;
- f->used_texturenames["torch.png"] = true;
+ f->used_texturenames.insert("torch_on_floor.png"); // Add to atlas
+ f->used_texturenames.insert("torch_on_ceiling.png"); // Add to atlas
+ f->used_texturenames.insert("torch.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
setConstantMaterialProperties(f->material, 0.0);
i = CONTENT_SIGN_WALL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("sign_wall.png", tsrc);
- f->used_texturenames["sign_wall.png"] = true;
+ f->used_texturenames.insert("sign_wall.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
f->selection_box.type = NODEBOX_WALLMOUNTED;
i = CONTENT_CHEST;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "chest_side.png");
f->setTexture(tsrc, 0, "chest_top.png");
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_LOCKABLE_CHEST;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "chest_side.png");
f->setTexture(tsrc, 0, "chest_top.png");
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_FURNACE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "furnace_side.png");
f->setTexture(tsrc, 5, "furnace_front.png"); // Z-
setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_COBBLE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cobble.png");
f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png", tsrc);
f->param_type = CPT_NONE;
setStoneLikeMaterialProperties(f->material, 0.9);
i = CONTENT_MOSSYCOBBLE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mossycobble.png");
f->setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png", tsrc);
f->param_type = CPT_NONE;
setStoneLikeMaterialProperties(f->material, 0.8);
i = CONTENT_STEEL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "steel_block.png");
f->setInventoryTextureCube("steel_block.png", "steel_block.png",
"steel_block.png", tsrc);
setStoneLikeMaterialProperties(f->material, 5.0);
i = CONTENT_NC;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "nc_side.png");
f->setTexture(tsrc, 5, "nc_front.png"); // Z-
setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_NC_RB;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "nc_rb.png");
f->setInventoryTexture("nc_rb.png", tsrc);
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_SAPLING;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_LIGHT;
f->setAllTextures(tsrc, "sapling.png");
f->setInventoryTexture("sapling.png", tsrc);
- f->used_texturenames["sapling.png"] = true;
+ f->used_texturenames.insert("sapling.png"); // Add to atlas
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->light_propagates = true;
f->air_equivalent = false;
setConstantMaterialProperties(f->material, 0.0);
i = CONTENT_APPLE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("apple.png", tsrc);
- f->used_texturenames["apple.png"] = true;
+ f->used_texturenames.insert("apple.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
#include "mapnode.h"
class ITextureSource;
+class IWritableNodeDefManager;
/*
- Fills stuff to the global ContentFeatures lookup table.
+ Initialize default node definitions
This accesses tsrc; if it is non-NULL, textures are set
for the nodes.
Server only calls this once with tsrc=NULL.
*/
-void content_mapnode_init(ITextureSource *tsrc);
+void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr);
// Backwards compatibility for non-extended content types in v19
extern content_t trans_table_19[21][2];
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
if(send_recommended == false)
return;
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground;
setBasePosition(pos_f);
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground;
// Do collision damage
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground;
setBasePosition(pos_f);
*/
#include "content_tool.h"
-#include "tool.h"
+#include "tooldef.h"
-void content_tool_init(IToolDefManager *mgr)
+void content_tool_init(IWritableToolDefManager *mgr)
{
mgr->registerTool("WPick",
ToolDefinition("tool_woodpick.png",
ToolDefinition("tool_steelsword.png",
ToolDiggingProperties(2.0, 3,0,1,-1, 300, 0,0,0,0)));
mgr->registerTool("",
- ToolDefinition("tool_hand.png",
+ ToolDefinition("tooldef.hand.png",
ToolDiggingProperties(0.5, 1,0,-1,0, 50, 0,0,0,0)));
}
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-class IToolDefManager;
+class IWritableToolDefManager;
// Add default tools to manager
-void content_tool_init(IToolDefManager *mgr);
+void content_tool_init(IWritableToolDefManager *mgr);
#include "log.h"
#include "profiler.h"
#include "scriptapi.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "nodemetadata.h"
#include "main.h" // For g_settings, g_profiler
+#include "gamedef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
- testplayer.deSerialize(is, m_gamedef);
+ testplayer.deSerialize(is);
}
//infostream<<"Loaded test player with name "<<testplayer.getName()<<std::endl;
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
- testplayer.deSerialize(is, m_gamedef);
+ testplayer.deSerialize(is);
}
if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS))
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
- player->deSerialize(is, m_gamedef);
+ player->deSerialize(is);
}
if(newplayer)
MapNode n = block->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE)
continue;
- if(content_features(n).liquid_type != LIQUID_NONE)
+ if(m_gamedef->ndef()->get(n).liquid_type != LIQUID_NONE)
continue;
- if(content_features(n).walkable)
+ if(m_gamedef->ndef()->get(n).walkable)
{
last_node_walkable = true;
continue;
if(last_node_walkable)
{
// If block contains light information
- if(content_features(n).param_type == CPT_LIGHT)
+ if(m_gamedef->ndef()->get(n).param_type == CPT_LIGHT)
{
if(n.getLight(LIGHTBANK_DAY) <= 5)
{
if(dtime_s > 300)
{
MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
- if(content_features(n_top).air_equivalent &&
- n_top.getLight(LIGHTBANK_DAY) >= 13)
+ if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+ n_top.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) >= 13)
{
n.setContent(CONTENT_GRASS);
m_map->addNodeWithEvent(p, n);
if(myrand()%20 == 0)
{
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
- if(content_features(n_top).air_equivalent &&
- n_top.getLightBlend(getDayNightRatio()) >= 13)
+ if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+ n_top.getLightBlend(getDayNightRatio(),
+ m_gamedef->ndef()) >= 13)
{
n.setContent(CONTENT_GRASS);
m_map->addNodeWithEvent(p, n);
//if(myrand()%20 == 0)
{
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
- if(content_features(n_top).air_equivalent == false)
+ if(m_gamedef->ndef()->get(n_top).air_equivalent == false)
{
n.setContent(CONTENT_MUD);
m_map->addNodeWithEvent(p, n);
{
v3s16 p1 = p + v3s16(0,1,0);
MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
- if(n1a.getLightBlend(getDayNightRatio()) <= 3){
+ if(n1a.getLightBlend(getDayNightRatio(),
+ m_gamedef->ndef()) <= 3){
MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
if(n1a.getContent() == CONTENT_AIR &&
n1b.getContent() == CONTENT_AIR)
u32 damage_per_second = 0;
damage_per_second = MYMAX(damage_per_second,
- content_features(n1).damage_per_second);
+ m_gamedef->ndef()->get(n1).damage_per_second);
damage_per_second = MYMAX(damage_per_second,
- content_features(n2).damage_per_second);
+ m_gamedef->ndef()->get(n2).damage_per_second);
damage_per_second = MYMAX(damage_per_second,
- content_features(n3).damage_per_second);
+ m_gamedef->ndef()->get(n3).damage_per_second);
if(damage_per_second != 0)
{
// Get node at head
v3s16 p = player->getLightPosition();
MapNode n = m_map->getNode(p);
- light = n.getLightBlend(getDayNightRatio());
+ light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
}
catch(InvalidPositionException &e) {}
player->updateLight(light);
// Get node at head
v3s16 p = obj->getLightPosition();
MapNode n = m_map->getNode(p);
- light = n.getLightBlend(getDayNightRatio());
+ light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
}
catch(InvalidPositionException &e) {}
obj->updateLight(light);
}
}
-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)
LocalPlayer * getLocalPlayer();
// Slightly deprecated
- void updateMeshes(v3s16 blockpos, ITextureSource *tsrc);
+ void updateMeshes(v3s16 blockpos);
void expireMeshes(bool only_daynight_diffed);
void setTimeOfDay(u32 time)
#include "log.h"
#include "filesys.h"
// Needed for determining pointing to nodes
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "nodemetadata.h"
#include "main.h" // For g_settings
#include "content_mapnode.h" // For content_mapnode_init
-#include "tool.h"
-#include "content_tool.h" // For content_tool_init
+#include "tooldef.h"
+#include "content_tool.h" // Default tools
+#include "content_mapnode.h" // Default nodes
/*
Setting this to 1 enables a special camera mode that forces
try
{
n = client->getNode(v3s16(x,y,z));
- if(content_pointable(n.getContent()) == false)
+ if(client->getNodeDefManager()->get(n).pointable == false)
continue;
}
catch(InvalidPositionException &e)
v3s16(-1,0,0), // left
};
- ContentFeatures &f = content_features(n);
+ const ContentFeatures &f = client->getNodeDefManager()->get(n);
if(f.selection_box.type == NODEBOX_FIXED)
{
draw_load_screen(L"Loading...", driver, font);
- // Create tool manager
- IToolDefManager *toolmgr = createToolDefManager();
-
+ // Create tool definition manager
+ IWritableToolDefManager *tooldef = createToolDefManager();
// Create texture source
- TextureSource *tsrc = new TextureSource(device);
-
- // Initialize mapnode again to enable changed graphics settings
- // Initialize content feature table with textures
- init_contentfeatures(tsrc);
- // Fill content feature table with default definitions
- content_mapnode_init(tsrc);
+ IWritableTextureSource *tsrc = createTextureSource(device);
+ // Create node definition manager
+ IWritableNodeDefManager *nodedef = createNodeDefManager(tsrc);
- // Initialize default tool definitions
- content_tool_init(toolmgr);
+ // Fill node feature table with default definitions
+ content_mapnode_init(tsrc, nodedef);
+ // Set default tool definitions
+ content_tool_init(tooldef);
/*
Create server.
draw_load_screen(L"Creating client...", driver, font);
infostream<<"Creating client"<<std::endl;
+
MapDrawControl draw_control;
+
Client client(device, playername.c_str(), password, draw_control,
- tsrc, toolmgr);
+ tsrc, tooldef, nodedef);
+
+ // Client acts as our GameDef
+ IGameDef *gamedef = &client;
draw_load_screen(L"Resolving address...", driver, font);
Address connect_address(0,0,0,0, port);
// Get digging properties for material and tool
content_t material = n.getContent();
ToolDiggingProperties tp =
- toolmgr->getDiggingProperties(toolname);
+ tooldef->getDiggingProperties(toolname);
DiggingProperties prop =
- getDiggingProperties(material, &tp);
+ getDiggingProperties(material, &tp, nodedef);
float dig_time_complete = 0.0;
InventoryItem *item = NULL;
if(mlist != NULL)
item = mlist->getItem(g_selected_item);
- camera.wield(item, tsrc);
+ camera.wield(item, gamedef);
}
/*
gui_shuttingdowntext->remove();*/
}
- delete toolmgr;
+ delete tooldef;
delete tsrc;
}
#define GAMEDEF_HEADER
class IToolDefManager;
-class INodeDefManager; //TODO
+class INodeDefManager;
//class IItemDefManager; //TODO
// Mineral too?
+class ITextureSource;
/*
An interface for fetching game-global definitions like tool and
class IGameDef
{
public:
+ // These are thread-safe IF they are not edited while running threads.
+ // Thus, first they are set up and then they are only read.
virtual IToolDefManager* getToolDefManager()=0;
virtual INodeDefManager* getNodeDefManager()=0;
//virtual IItemDefManager* getItemDefManager()=0;
+
+ // This is always thread-safe, but referencing the irrlicht texture
+ // pointers in other threads than main thread will make things explode.
+ virtual ITextureSource* getTextureSource()=0;
+
+ // Shorthands
+ IToolDefManager* tdef(){return getToolDefManager();}
+ INodeDefManager* ndef(){return getNodeDefManager();}
+ ITextureSource* tsrc(){return getTextureSource();}
};
#endif
#include "content_sao.h"
#include "player.h"
#include "log.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
#include "gamedef.h"
/*
#ifndef SERVER
video::ITexture * MaterialItem::getImage(ITextureSource *tsrc) const
{
- return content_features(m_content).inventory_texture;
+ return m_gamedef->getNodeDefManager()->get(m_content).inventory_texture;
}
#endif
#include "settings.h"
#include "profiler.h"
#include "log.h"
-#include "mapnode_contentfeatures.h" // For init_contentfeatures
+#include "nodedef.h" // For init_contentfeatures
#include "content_mapnode.h" // For content_mapnode_init
/*
These are needed for unit tests at least.
*/
- // Initialize content feature table without textures
- init_contentfeatures(NULL);
- // Initialize mapnode content without textures
- content_mapnode_init(NULL);
// Must be called before texturesource is created
// (for texture atlas making)
init_mineral();
#include "settings.h"
#include "log.h"
#include "profiler.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
core::map<v3s16, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node)
*/
- if(n2.getLight(bank) < oldlight)
+ if(n2.getLight(bank, nodemgr) < oldlight)
{
/*
And the neighbor is transparent and it has some light
*/
- if(n2.light_propagates() && n2.getLight(bank) != 0)
+ if(nodemgr->get(n2).light_propagates
+ && n2.getLight(bank, nodemgr) != 0)
{
/*
Set light to 0 and add to queue
*/
- u8 current_light = n2.getLight(bank);
- n2.setLight(bank, 0);
+ u8 current_light = n2.getLight(bank, nodemgr);
+ n2.setLight(bank, 0, nodemgr);
block->setNode(relpos, n2);
unlighted_nodes.insert(n2pos, current_light);
core::map<v3s16, bool> & from_nodes,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
const v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
// Get node straight from the block
MapNode n = block->getNode(relpos);
- u8 oldlight = n.getLight(bank);
+ u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors
If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn)
*/
- if(n2.getLight(bank) > undiminish_light(oldlight))
+ if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
{
lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos);
If the neighbor is dimmer than how much light this node
would spread on it, add to list
*/
- if(n2.getLight(bank) < newlight)
+ if(n2.getLight(bank, nodemgr) < newlight)
{
- if(n2.light_propagates())
+ if(nodemgr->get(n2).light_propagates)
{
- n2.setLight(bank, newlight);
+ n2.setLight(bank, newlight, nodemgr);
block->setNode(relpos, n2);
lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos);
v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
{
continue;
}
- if(n2.getLight(bank) > brightest_light || found_something == false){
- brightest_light = n2.getLight(bank);
+ if(n2.getLight(bank, nodemgr) > brightest_light || found_something == false){
+ brightest_light = n2.getLight(bank, nodemgr);
brightest_pos = n2pos;
found_something = true;
}
s16 Map::propagateSunlight(v3s16 start,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
s16 y = start.Y;
for(; ; y--)
{
v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE;
MapNode n = block->getNode(relpos);
- if(n.sunlight_propagates())
+ if(nodemgr->get(n).sunlight_propagates)
{
- n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+ n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
block->setNode(relpos, n);
modified_blocks.insert(blockpos, block);
core::map<v3s16, MapBlock*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
/*m_dout<<DTIME<<"Map::updateLighting(): "
<<a_blocks.size()<<" blocks."<<std::endl;*/
try{
v3s16 p(x,y,z);
MapNode n = block->getNode(v3s16(x,y,z));
- u8 oldlight = n.getLight(bank);
- n.setLight(bank, 0);
+ u8 oldlight = n.getLight(bank, nodemgr);
+ n.setLight(bank, 0, nodemgr);
block->setNode(v3s16(x,y,z), n);
// Collect borders for unlighting
{
//TimeTaker timer("unSpreadLight");
- vmanip.unspreadLight(bank, unlight_from, light_sources);
+ vmanip.unspreadLight(bank, unlight_from, light_sources, nodemgr);
}
{
//TimeTaker timer("spreadLight");
- vmanip.spreadLight(bank, light_sources);
+ vmanip.spreadLight(bank, light_sources, nodemgr);
}
{
//TimeTaker timer("blitBack");
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
/*PrintInfo(m_dout);
m_dout<<DTIME<<"Map::addNodeAndUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
try{
MapNode topnode = getNode(toppos);
- if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+ if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
node_under_sunlight = false;
}
catch(InvalidPositionException &e)
/*
If the new node is solid and there is grass below, change it to mud
*/
- if(content_features(n).walkable == true)
+ if(nodemgr->get(n).walkable == true)
{
try{
MapNode bottomnode = getNode(bottompos);
{
enum LightBank bank = banks[i];
- u8 lightwas = getNode(p).getLight(bank);
+ u8 lightwas = getNode(p).getLight(bank, nodemgr);
// Add the block of the added node to modified_blocks
v3s16 blockpos = getNodeBlockPos(p);
// light again into this.
unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks);
- n.setLight(bank, 0);
+ n.setLight(bank, 0, nodemgr);
}
/*
If node lets sunlight through and is under sunlight, it has
sunlight too.
*/
- if(node_under_sunlight && content_features(n).sunlight_propagates)
+ if(node_under_sunlight && nodemgr->get(n).sunlight_propagates)
{
- n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+ n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
}
/*
Add intial metadata
*/
- NodeMetadata *meta_proto = content_features(n).initial_metadata;
+ NodeMetadata *meta_proto = nodemgr->get(n).initial_metadata;
if(meta_proto)
{
NodeMetadata *meta = meta_proto->clone(m_gamedef);
TODO: This could be optimized by mass-unlighting instead
of looping
*/
- if(node_under_sunlight && !content_features(n).sunlight_propagates)
+ if(node_under_sunlight && !nodemgr->get(n).sunlight_propagates)
{
s16 y = p.Y - 1;
for(;; y--){
break;
}
- if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+ if(n2.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
{
unLightNeighbors(LIGHTBANK_DAY,
- n2pos, n2.getLight(LIGHTBANK_DAY),
+ n2pos, n2.getLight(LIGHTBANK_DAY, nodemgr),
light_sources, modified_blocks);
- n2.setLight(LIGHTBANK_DAY, 0);
+ n2.setLight(LIGHTBANK_DAY, 0, nodemgr);
setNode(n2pos, n2);
}
else
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
- if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
+ if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
{
m_transforming_liquid.push_back(p2);
}
void Map::removeNodeAndUpdate(v3s16 p,
core::map<v3s16, MapBlock*> &modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
/*PrintInfo(m_dout);
m_dout<<DTIME<<"Map::removeNodeAndUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
try{
MapNode topnode = getNode(toppos);
- if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+ if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
node_under_sunlight = false;
}
catch(InvalidPositionException &e)
Unlight neighbors (in case the node is a light source)
*/
unLightNeighbors(bank, p,
- getNode(p).getLight(bank),
+ getNode(p).getLight(bank, nodemgr),
light_sources, modified_blocks);
}
// TODO: Is this needed? Lighting is cleared up there already.
try{
MapNode n = getNode(p);
- n.setLight(LIGHTBANK_DAY, 0);
+ n.setLight(LIGHTBANK_DAY, 0, nodemgr);
setNode(p, n);
}
catch(InvalidPositionException &e)
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
- if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
+ if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
{
m_transforming_liquid.push_back(p2);
}
void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
DSTACK(__FUNCTION_NAME);
//TimeTaker timer("transformLiquids()");
*/
s8 liquid_level = -1;
u8 liquid_kind = CONTENT_IGNORE;
- LiquidType liquid_type = content_features(n0.getContent()).liquid_type;
+ LiquidType liquid_type = nodemgr->get(n0).liquid_type;
switch (liquid_type) {
case LIQUID_SOURCE:
liquid_level = LIQUID_LEVEL_SOURCE;
- liquid_kind = content_features(n0.getContent()).liquid_alternative_flowing;
+ liquid_kind = nodemgr->get(n0).liquid_alternative_flowing;
break;
case LIQUID_FLOWING:
liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
}
v3s16 npos = p0 + dirs[i];
NodeNeighbor nb = {getNodeNoEx(npos), nt, npos};
- switch (content_features(nb.n.getContent()).liquid_type) {
+ switch (nodemgr->get(nb.n.getContent()).liquid_type) {
case LIQUID_NONE:
if (nb.n.getContent() == CONTENT_AIR) {
airs[num_airs++] = nb;
case LIQUID_SOURCE:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if (liquid_kind == CONTENT_AIR)
- liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
- if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
+ liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
+ if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
sources[num_sources++] = nb;
case LIQUID_FLOWING:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if (liquid_kind == CONTENT_AIR)
- liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
- if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
+ liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
+ if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
flows[num_flows++] = nb;
// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
// or the flowing alternative of the first of the surrounding sources (if it's air), so
// it's perfectly safe to use liquid_kind here to determine the new node content.
- new_node_content = content_features(liquid_kind).liquid_alternative_source;
+ new_node_content = nodemgr->get(liquid_kind).liquid_alternative_source;
} else if (num_sources == 1 && sources[0].t != NEIGHBOR_LOWER) {
// liquid_kind is set properly, see above
new_node_content = liquid_kind;
}
}
- u8 viscosity = content_features(liquid_kind).liquid_viscosity;
+ u8 viscosity = nodemgr->get(liquid_kind).liquid_viscosity;
if (viscosity > 1 && max_node_level != liquid_level) {
// amount to gain, limited by viscosity
// must be at least 1 in absolute value
/*
check if anything has changed. if not, just continue with the next node.
*/
- if (new_node_content == n0.getContent() && (content_features(n0.getContent()).liquid_type != LIQUID_FLOWING ||
+ if (new_node_content == n0.getContent() && (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
== flowing_down)))
update the current node
*/
//bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
- if (content_features(new_node_content).liquid_type == LIQUID_FLOWING) {
+ if (nodemgr->get(new_node_content).liquid_type == LIQUID_FLOWING) {
// set level to last 3 bits, flowing down bit to 4th bit
n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
} else {
if(block != NULL) {
modified_blocks.insert(blockpos, block);
// If node emits light, MapBlock requires lighting update
- if(content_features(n0).light_source != 0)
+ if(nodemgr->get(n0).light_source != 0)
lighting_modified_blocks[block->getPos()] = block;
}
/*
enqueue neighbors for update if neccessary
*/
- switch (content_features(n0.getContent()).liquid_type) {
+ switch (nodemgr->get(n0.getContent()).liquid_type) {
case LIQUID_SOURCE:
case LIQUID_FLOWING:
// make sure source flows into all neighboring nodes
data->no_op = false;
data->seed = m_seed;
data->blockpos = blockpos;
+ data->nodemgr = m_gamedef->ndef();
/*
Create the whole area of this and the neighboring blocks
Generate blank sector
*/
- sector = new ServerMapSector(this, p2d);
+ sector = new ServerMapSector(this, p2d, m_gamedef);
// Sector position on map in nodes
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
<<fullpath<<" doesn't exist but directory does."
<<" Continuing with a sector with no metadata."
<<std::endl;*/
- sector = new ServerMapSector(this, p2d);
+ sector = new ServerMapSector(this, p2d, m_gamedef);
m_sectors.insert(p2d, sector);
}
else
else
{
sector = ServerMapSector::deSerialize
- (is, this, p2d, m_sectors);
+ (is, this, p2d, m_sectors, m_gamedef);
if(save_after_load)
saveSectorMeta(sector);
}
}
// Read basic data
- block->deSerialize(is, version, m_gamedef);
+ block->deSerialize(is, version);
// Read extra data stored on disk
block->deSerializeDiskExtra(is, version);
}
// Read basic data
- block->deSerialize(is, version, m_gamedef);
+ block->deSerialize(is, version);
// Read extra data stored on disk
block->deSerializeDiskExtra(is, version);
}
// 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
}
static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
- float start_off, float end_off, u32 needed_count)
+ float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr)
{
float d0 = (float)BS * p0.getDistanceFrom(p1);
v3s16 u0 = p1 - p0;
v3s16 p = floatToInt(pf, BS);
MapNode n = map->getNodeNoEx(p);
bool is_transparent = false;
- ContentFeatures &f = content_features(n);
+ const ContentFeatures &f = nodemgr->get(n);
if(f.solidness == 0)
is_transparent = (f.visual_solidness != 2);
else
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
//m_dout<<DTIME<<"Rendering map..."<<std::endl;
DSTACK(__FUNCTION_NAME);
u32 needed_count = 1;
if(
isOccluded(this, spn, cpn + v3s16(0,0,0),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,-bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,-bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count)
+ step, stepfac, startoff, endoff, needed_count, nodemgr)
)
{
blocks_occlusion_culled++;
void ClientMap::renderPostFx()
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
// Sadly ISceneManager has no "post effects" render pass, in that case we
// could just register for that and handle it in renderMap().
// - If the player is in a solid node, make everything black.
// - If the player is in liquid, draw a semi-transparent overlay.
- ContentFeatures& features = content_features(n);
+ const ContentFeatures& features = nodemgr->get(n);
video::SColor post_effect_color = features.post_effect_color;
if(features.solidness == 2 && g_settings->getBool("free_move") == false)
{
}
}
-void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
- ITextureSource *tsrc)
+void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
{
assert(mapType() == MAPTYPE_CLIENT);
try{
v3s16 p = blockpos + v3s16(0,0,0);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(0,-1,0);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(0,0,-1);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
Update the faces of the given block and blocks on the
leading edge, without threading. Rarely used.
*/
- void updateMeshes(v3s16 blockpos, u32 daynight_ratio,
- ITextureSource *tsrc);
+ void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
// Update meshes that touch the node
//void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
#include "main.h"
#include "light.h"
#include <sstream>
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "nodemetadata.h"
+#include "gamedef.h"
/*
MapBlock
*/
-MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
+MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
m_node_metadata(new NodeMetadataList),
m_parent(parent),
m_pos(pos),
+ m_gamedef(gamedef),
m_modified(MOD_STATE_WRITE_NEEDED),
is_underground(false),
m_lighting_expired(true),
#ifndef SERVER
#if 1
-void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc)
+void MapBlock::updateMesh(u32 daynight_ratio)
{
#if 0
/*
MeshMakeData data;
data.fill(daynight_ratio, this);
- scene::SMesh *mesh_new = makeMapBlockMesh(&data, tsrc);
+ scene::SMesh *mesh_new = makeMapBlockMesh(&data, m_gamedef);
/*
Replace the mesh
bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
bool remove_light, bool *black_air_left)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
// Whether the sunlight at the top of the bottom block is valid
bool block_below_is_valid = true;
// Trust heuristics
no_sunlight = is_underground;
}
- else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+ else if(n.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) != LIGHT_SUN)
{
no_sunlight = true;
}
{
MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
//if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
- if(content_features(n).sunlight_propagates == false)
+ if(m_gamedef->ndef()->get(n).sunlight_propagates == false)
{
no_sunlight = true;
}
{
// Do nothing
}
- else if(current_light == LIGHT_SUN && n.sunlight_propagates())
+ else if(current_light == LIGHT_SUN && nodemgr->get(n).sunlight_propagates)
{
// Do nothing: Sunlight is continued
}
- else if(n.light_propagates() == false)
+ else if(nodemgr->get(n).light_propagates == false)
{
/*// DEPRECATED TODO: REMOVE
if(grow_grass)
current_light = diminish_light(current_light);
}
- u8 old_light = n.getLight(LIGHTBANK_DAY);
+ u8 old_light = n.getLight(LIGHTBANK_DAY, nodemgr);
if(current_light > old_light || remove_light)
{
- n.setLight(LIGHTBANK_DAY, current_light);
+ n.setLight(LIGHTBANK_DAY, current_light, nodemgr);
}
if(diminish_light(current_light) != 0)
if(block_below_is_valid)
{
MapNode n = getNodeParent(v3s16(x, -1, z));
- if(n.light_propagates())
+ if(nodemgr->get(n).light_propagates)
{
- if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN
+ if(n.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN
&& sunlight_should_go_down == false)
block_below_is_valid = false;
- else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN
+ else if(n.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN
&& sunlight_should_go_down == true)
block_below_is_valid = false;
}
void MapBlock::updateDayNightDiff()
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
if(data == NULL)
{
m_day_night_differs = false;
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
{
MapNode &n = data[i];
- if(n.getLight(LIGHTBANK_DAY) != n.getLight(LIGHTBANK_NIGHT))
+ if(n.getLight(LIGHTBANK_DAY, nodemgr) != n.getLight(LIGHTBANK_NIGHT, nodemgr))
{
differs = true;
break;
for(; y>=0; y--)
{
MapNode n = getNodeRef(p2d.X, y, p2d.Y);
- if(content_features(n).walkable)
+ if(m_gamedef->ndef()->get(n).walkable)
{
if(y == MAP_BLOCKSIZE-1)
return -2;
}
}
-void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
+void MapBlock::deSerialize(std::istream &is, u8 version)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapBlock format not supported");
if(is.gcount() != len)
throw SerializationError
("MapBlock::deSerialize: no enough input data");
- data[i].deSerialize(*d, version);
+ data[i].deSerialize(*d, version, nodemgr);
}
}
else if(version <= 10)
buf[0] = s[i];
buf[1] = s[i+nodecount];
buf[2] = s[i+nodecount*2];
- data[i].deSerialize(buf, version);
+ data[i].deSerialize(buf, version, m_gamedef->getNodeDefManager());
}
/*
{
std::string data = deSerializeString(is);
std::istringstream iss(data, std::ios_base::binary);
- m_node_metadata->deSerialize(iss, gamedef);
+ m_node_metadata->deSerialize(iss, m_gamedef);
}
else
{
std::ostringstream oss(std::ios_base::binary);
decompressZlib(is, oss);
std::istringstream iss(oss.str(), std::ios_base::binary);
- m_node_metadata->deSerialize(iss, gamedef);
+ m_node_metadata->deSerialize(iss, m_gamedef);
}
}
catch(SerializationError &e)
class Map;
class NodeMetadataList;
-class ITextureSource;
class IGameDef;
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
class MapBlock /*: public NodeContainer*/
{
public:
- MapBlock(Map *parent, v3s16 pos, bool dummy=false);
+ MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy=false);
~MapBlock();
/*virtual u16 nodeContainerId() const
getNodeParentNoEx(p + face_dir),
face_dir);
}*/
- u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
+ u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir,
+ INodeDefManager *nodemgr)
{
return getFaceLight(daynight_ratio,
getNodeParentNoEx(p),
getNodeParentNoEx(p + face_dir),
- face_dir);
+ face_dir, nodemgr);
}
#ifndef SERVER // Only on client
NOTE: Prefer generating the mesh separately and then using
replaceMesh().
*/
- void updateMesh(u32 daynight_ratio, ITextureSource *tsrc);
+ void updateMesh(u32 daynight_ratio);
#endif
// Replace the mesh with a new one
void replaceMesh(scene::SMesh *mesh_new);
// These don't write or read version by itself
void serialize(std::ostream &os, u8 version);
- void deSerialize(std::istream &is, u8 version, IGameDef *gamedef);
+ void deSerialize(std::istream &is, u8 version);
// Used after the basic ones when writing on disk (serverside)
void serializeDiskExtra(std::ostream &os, u8 version);
void deSerializeDiskExtra(std::istream &is, u8 version);
Map *m_parent;
// Position in blocks on parent
v3s16 m_pos;
+
+ IGameDef *m_gamedef;
/*
If NULL, block is a dummy block.
#include "mapblock.h"
#include "map.h"
#include "main.h" // For g_settings and g_texturesource
-#include "content_mapblock.h"
#include "settings.h"
#include "profiler.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "tile.h"
+#include "gamedef.h"
+#include "content_mapblock.h"
void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
{
/*
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:
video::S3DVertex vertices[4]; // Precalculated vertices
};
-void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
+static void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
v3s16 dir, v3f scale, v3f posRelative_f,
core::array<FastFace> &dest)
{
Gets node tile from any place relative to block.
Returns TILE_NODE if doesn't exist or should not be drawn.
*/
-TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
- NodeModMap &temp_mods, ITextureSource *tsrc)
+static TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
+ NodeModMap &temp_mods, ITextureSource *tsrc, INodeDefManager *ndef)
{
TileSpec spec;
- spec = mn.getTile(face_dir, tsrc);
+ spec = mn.getTile(face_dir, tsrc, ndef);
/*
Check temporary modifications on this node
if(mod.type == NODEMOD_CHANGECONTENT)
{
MapNode mn2(mod.param);
- spec = mn2.getTile(face_dir, tsrc);
+ spec = mn2.getTile(face_dir, tsrc, ndef);
}
if(mod.type == NODEMOD_CRACK)
{
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
};
// Calculate lighting at the XYZ- corner of p
-u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
+static u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio,
+ INodeDefManager *ndef)
{
u16 ambient_occlusion = 0;
u16 light = 0;
for(u32 i=0; i<8; i++)
{
MapNode n = vmanip.getNodeNoEx(p - dirs8[i]);
- if(content_features(n).param_type == CPT_LIGHT
+ if(ndef->get(n).param_type == CPT_LIGHT
// Fast-style leaves look better this way
- && content_features(n).solidness != 2)
+ && ndef->get(n).solidness != 2)
{
- light += decode_light(n.getLightBlend(daynight_ratio));
+ light += decode_light(n.getLightBlend(daynight_ratio, ndef));
light_count++;
}
else
}
// Calculate lighting at the given corner of p
-u8 getSmoothLight(v3s16 p, v3s16 corner,
- VoxelManipulator &vmanip, u32 daynight_ratio)
+static u8 getSmoothLight(v3s16 p, v3s16 corner,
+ VoxelManipulator &vmanip, u32 daynight_ratio, INodeDefManager *ndef)
{
if(corner.X == 1) p.X += 1;
else assert(corner.X == -1);
if(corner.Z == 1) p.Z += 1;
else assert(corner.Z == -1);
- return getSmoothLight(p, vmanip, daynight_ratio);
+ return getSmoothLight(p, vmanip, daynight_ratio, ndef);
}
-void getTileInfo(
+static void getTileInfo(
// Input:
v3s16 blockpos_nodes,
v3s16 p,
VoxelManipulator &vmanip,
NodeModMap &temp_mods,
bool smooth_lighting,
- ITextureSource *tsrc,
+ IGameDef *gamedef,
// Output:
bool &makes_face,
v3s16 &p_corrected,
TileSpec &tile
)
{
+ ITextureSource *tsrc = gamedef->tsrc();
+ INodeDefManager *ndef = gamedef->ndef();
+
MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
- TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods, tsrc);
- TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc);
+ TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods, tsrc, ndef);
+ TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc, ndef);
// This is hackish
content_t content0 = getNodeContent(p, n0, temp_mods);
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
bool equivalent = false;
- u8 mf = face_contents(content0, content1, &equivalent);
+ u8 mf = face_contents(content0, content1, &equivalent, ndef);
if(mf == 0)
{
if(smooth_lighting == false)
{
lights[0] = lights[1] = lights[2] = lights[3] =
- decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir));
+ decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir, ndef));
}
else
{
for(u16 i=0; i<4; i++)
{
lights[i] = getSmoothLight(blockpos_nodes + p_corrected,
- vertex_dirs[i], vmanip, daynight_ratio);
+ vertex_dirs[i], vmanip, daynight_ratio, ndef);
}
}
translate_dir: unit vector with only one of x, y or z
face_dir: unit vector with only one of x, y or z
*/
-void updateFastFaceRow(
+static void updateFastFaceRow(
u32 daynight_ratio,
v3f posRelative_f,
v3s16 startpos,
VoxelManipulator &vmanip,
v3s16 blockpos_nodes,
bool smooth_lighting,
- ITextureSource *tsrc)
+ IGameDef *gamedef)
{
v3s16 p = startpos;
u8 lights[4] = {0,0,0,0};
TileSpec tile;
getTileInfo(blockpos_nodes, p, face_dir, daynight_ratio,
- vmanip, temp_mods, smooth_lighting, tsrc,
+ vmanip, temp_mods, smooth_lighting, gamedef,
makes_face, p_corrected, face_dir_corrected, lights, tile);
for(u16 j=0; j<length; j++)
p_next = p + translate_dir;
getTileInfo(blockpos_nodes, p_next, face_dir, daynight_ratio,
- vmanip, temp_mods, smooth_lighting, tsrc,
+ vmanip, temp_mods, smooth_lighting, gamedef,
next_makes_face, next_p_corrected,
next_face_dir_corrected, next_lights,
next_tile);
}
}
-scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
+scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef)
{
// 4-21ms for MAP_BLOCKSIZE=16
// 24-155ms for MAP_BLOCKSIZE=32
data->m_vmanip,
blockpos_nodes,
smooth_lighting,
- tsrc);
+ gamedef);
}
}
/*
data->m_vmanip,
blockpos_nodes,
smooth_lighting,
- tsrc);
+ gamedef);
}
}
/*
data->m_vmanip,
blockpos_nodes,
smooth_lighting,
- tsrc);
+ gamedef);
}
}
}
- whatever
*/
- mapblock_mesh_generate_special(data, collector, tsrc);
+ mapblock_mesh_generate_special(data, collector, gamedef);
/*
Add stuff from collector to mesh
#include "mapblock_nodemod.h"
#include "voxel.h"
+class IGameDef;
+
/*
Mesh making stuff
*/
};
// This is the highest-level function in here
-scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc);
+scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef);
#endif
#include "mineral.h"
//#include "serverobject.h"
#include "content_sao.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
namespace mapgen
{
MapNode n = block->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE)
continue;
- if(content_features(n).liquid_type != LIQUID_NONE)
+ if(data->nodemgr->get(n)->liquid_type != LIQUID_NONE)
continue;
- if(content_features(n).walkable)
+ if(data->nodemgr->get(n)->walkable)
{
last_node_walkable = true;
continue;
return;
}
+ assert(data->vmanip);
+ assert(data->nodemgr);
+
v3s16 blockpos = data->blockpos;
/*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
{
u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i];
- if(content_features(*n).is_ground_content
+ if(data->nodemgr->get(*n).is_ground_content
|| n->getContent() == CONTENT_JUNGLETREE)
{
found = true;
BlockMakeData::BlockMakeData():
no_op(false),
vmanip(NULL),
- seed(0)
+ seed(0),
+ nodemgr(NULL)
{}
BlockMakeData::~BlockMakeData()
struct BlockMakeData;
class MapBlock;
class ManualMapVoxelManipulator;
+class INodeDefManager;
namespace mapgen
{
struct BlockMakeData
{
bool no_op;
- ManualMapVoxelManipulator *vmanip;
+ ManualMapVoxelManipulator *vmanip; // Destructor deletes
u64 seed;
v3s16 blockpos;
UniqueQueue<v3s16> transforming_liquid;
+ INodeDefManager *nodemgr; // Destructor deletes
BlockMakeData();
~BlockMakeData();
#include <string>
#include "mineral.h"
#include "main.h" // For g_settings
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "content_mapnode.h" // For mapnode_translate_*_internal
/*
1: Face uses m1's content
2: Face uses m2's content
equivalent: Whether the blocks share the same face (eg. water and glass)
+
+ TODO: Add 3: Both faces drawn with backface culling, remove equivalent
*/
-u8 face_contents(content_t m1, content_t m2, bool *equivalent)
+u8 face_contents(content_t m1, content_t m2, bool *equivalent,
+ INodeDefManager *nodemgr)
{
*equivalent = false;
bool contents_differ = (m1 != m2);
+ const ContentFeatures &f1 = nodemgr->get(m1);
+ const ContentFeatures &f2 = nodemgr->get(m2);
+
// Contents don't differ for different forms of same liquid
- if(content_liquid(m1) && content_liquid(m2)
- && make_liquid_flowing(m1) == make_liquid_flowing(m2))
+ if(f1.sameLiquid(f2))
contents_differ = false;
- u8 c1 = content_solidness(m1);
- u8 c2 = content_solidness(m2);
+ u8 c1 = f1.solidness;
+ u8 c2 = f2.solidness;
bool solidness_differs = (c1 != c2);
bool makes_face = contents_differ && solidness_differs;
return 0;
if(c1 == 0)
- c1 = content_features(m1).visual_solidness;
+ c1 = f1.visual_solidness;
if(c2 == 0)
- c2 = content_features(m2).visual_solidness;
+ c2 = f2.visual_solidness;
if(c1 == c2){
*equivalent = true;
// If same solidness, liquid takes precense
- if(content_features(m1).liquid_type != LIQUID_NONE)
+ if(f1.isLiquid())
return 1;
- if(content_features(m2).liquid_type != LIQUID_NONE)
+ if(f2.isLiquid())
return 2;
}
MapNode
*/
-// These four are DEPRECATED.
-bool MapNode::light_propagates()
-{
- return light_propagates_content(getContent());
-}
-bool MapNode::sunlight_propagates()
-{
- return sunlight_propagates_content(getContent());
-}
-u8 MapNode::solidness()
-{
- return content_solidness(getContent());
-}
-u8 MapNode::light_source()
-{
- return content_features(*this).light_source;
-}
-
-void MapNode::setLight(enum LightBank bank, u8 a_light)
+void MapNode::setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr)
{
// If node doesn't contain light data, ignore this
- if(content_features(*this).param_type != CPT_LIGHT)
+ if(nodemgr->get(*this).param_type != CPT_LIGHT)
return;
if(bank == LIGHTBANK_DAY)
{
assert(0);
}
-u8 MapNode::getLight(enum LightBank bank)
+u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
u8 light = 0;
- if(content_features(*this).param_type == CPT_LIGHT)
+ if(nodemgr->get(*this).param_type == CPT_LIGHT)
{
if(bank == LIGHTBANK_DAY)
light = param1 & 0x0f;
else
assert(0);
}
- if(light_source() > light)
- light = light_source();
+ if(nodemgr->get(*this).light_source > light)
+ light = nodemgr->get(*this).light_source;
return light;
}
-u8 MapNode::getLightBanksWithSource()
+u8 MapNode::getLightBanksWithSource(INodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
u8 lightday = 0;
u8 lightnight = 0;
- if(content_features(*this).param_type == CPT_LIGHT)
+ if(nodemgr->get(*this).param_type == CPT_LIGHT)
{
lightday = param1 & 0x0f;
lightnight = (param1>>4)&0x0f;
}
- if(light_source() > lightday)
- lightday = light_source();
- if(light_source() > lightnight)
- lightnight = light_source();
+ if(nodemgr->get(*this).light_source > lightday)
+ lightday = nodemgr->get(*this).light_source;
+ if(nodemgr->get(*this).light_source > lightnight)
+ lightnight = nodemgr->get(*this).light_source;
return (lightday&0x0f) | ((lightnight<<4)&0xf0);
}
#ifndef SERVER
-TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
+TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc,
+ INodeDefManager *nodemgr) const
{
- if(content_features(*this).param_type == CPT_FACEDIR_SIMPLE)
+ if(nodemgr->get(*this).param_type == CPT_FACEDIR_SIMPLE)
dir = facedir_rotate(param1, dir);
TileSpec spec;
if(dir_i == -1)
// Non-directional
- spec = content_features(*this).tiles[0];
+ spec = nodemgr->get(*this).tiles[0];
else
- spec = content_features(*this).tiles[dir_i];
+ spec = nodemgr->get(*this).tiles[dir_i];
/*
If it contains some mineral, change texture id
*/
- if(content_features(*this).param_type == CPT_MINERAL && tsrc)
+ if(nodemgr->get(*this).param_type == CPT_MINERAL && tsrc)
{
- u8 mineral = getMineral();
+ u8 mineral = getMineral(nodemgr);
std::string mineral_texture_name = mineral_block_texture(mineral);
if(mineral_texture_name != "")
{
}
#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;
}
dest[2] = n_foreign.param2;
}
}
-void MapNode::deSerialize(u8 *source, u8 version)
+void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
{
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported");
{
param0 = source[0];
// This version doesn't support saved lighting
- if(light_propagates() || light_source() > 0)
+ if(nodemgr->get(*this).light_propagates || nodemgr->get(*this).light_source > 0)
param1 = 0;
else
param1 = source[1];
returns encoded light value.
*/
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
- v3s16 face_dir)
+ v3s16 face_dir, INodeDefManager *nodemgr)
{
try{
u8 light;
- u8 l1 = n.getLightBlend(daynight_ratio);
- u8 l2 = n2.getLightBlend(daynight_ratio);
+ u8 l1 = n.getLightBlend(daynight_ratio, nodemgr);
+ u8 l2 = n2.getLightBlend(daynight_ratio, nodemgr);
if(l1 > l2)
light = l1;
else
#include "tile.h"
#endif
+class INodeDefManager;
+
/*
Naming scheme:
- Material = irrlicht's Material class
2: Face uses m2's content
equivalent: Whether the blocks share the same face (eg. water and glass)
*/
-u8 face_contents(content_t m1, content_t m2, bool *equivalent);
+u8 face_contents(content_t m1, content_t m2, bool *equivalent,
+ INodeDefManager *nodemgr);
/*
Packs directions like (1,0,0), (1,-1,0) in six bits.
}
// To be used everywhere
- content_t getContent()
+ content_t getContent() const
{
if(param0 < 0x80)
return param0;
}
}
- /*
- These four are DEPRECATED I guess. -c55
- */
- bool light_propagates();
- bool sunlight_propagates();
- u8 solidness();
- u8 light_source();
-
- void setLight(enum LightBank bank, u8 a_light);
- u8 getLight(enum LightBank bank);
- u8 getLightBanksWithSource();
+ void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
+ u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
+ u8 getLightBanksWithSource(INodeDefManager *nodemgr) const;
// 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN
- u8 getLightBlend(u32 daylight_factor)
+ u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
{
- u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
- + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
+ u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY, nodemgr)
+ + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT, nodemgr))
)/1000;
u8 max = LIGHT_MAX;
- if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+ if(getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
max = LIGHT_SUN;
if(l > max)
l = max;
}
/*// 0 <= daylight_factor <= 1000
// 0 <= return value <= 255
- u8 getLightBlend(u32 daylight_factor)
+ u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr)
{
- u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
- u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
+ u8 daylight = decode_light(getLight(LIGHTBANK_DAY, nodemgr));
+ u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT, nodemgr));
u8 mix = ((daylight_factor * daylight
+ (1000-daylight_factor) * nightlight)
)/1000;
Returns: TileSpec. Can contain miscellaneous texture coordinates,
which must be obeyed so that the texture atlas can be used.
*/
- TileSpec getTile(v3s16 dir, ITextureSource *tsrc);
+ TileSpec getTile(v3s16 dir, ITextureSource *tsrc,
+ INodeDefManager *nodemgr) const;
#endif
/*
Gets mineral content of node, if there is any.
MINERAL_NONE if doesn't contain or isn't able to contain mineral.
*/
- u8 getMineral();
+ u8 getMineral(INodeDefManager *nodemgr) const;
/*
Serialization functions
static u32 serializedLength(u8 version);
void serialize(u8 *dest, u8 version);
- void deSerialize(u8 *source, u8 version);
+ void deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr);
};
returns encoded light value.
*/
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
- v3s16 face_dir);
+ v3s16 face_dir, INodeDefManager *nodemgr);
#endif
+++ /dev/null
-/*
-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());
-}
-
-
+++ /dev/null
-/*
-Minetest-c55
-Copyright (C) 2010-2011 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.
-*/
-
-#ifndef MAPNODE_CONTENTFEATURES_HEADER
-#define MAPNODE_CONTENTFEATURES_HEADER
-
-#include "common_irrlicht.h"
-#include <string>
-#include "mapnode.h"
-#ifndef SERVER
-#include "tile.h"
-#endif
-#include "materials.h" // MaterialProperties
-class ITextureSource;
-
-/*
- Content feature list
-
- Used for determining properties of MapNodes by content type without
- storing such properties in the nodes itself.
-*/
-
-/*
- Initialize content feature table.
-
- Must be called before accessing the table.
-*/
-void init_contentfeatures(ITextureSource *tsrc);
-
-enum ContentParamType
-{
- CPT_NONE,
- CPT_LIGHT,
- CPT_MINERAL,
- // Direction for chests and furnaces and such
- CPT_FACEDIR_SIMPLE
-};
-
-enum LiquidType
-{
- LIQUID_NONE,
- LIQUID_FLOWING,
- LIQUID_SOURCE
-};
-
-enum NodeBoxType
-{
- NODEBOX_REGULAR, // Regular block; allows buildable_to
- NODEBOX_FIXED, // Static separately defined box
- NODEBOX_WALLMOUNTED, // Box for wall_mounted nodes; (top, bottom, side)
-};
-
-struct NodeBox
-{
- enum NodeBoxType type;
- // NODEBOX_REGULAR (no parameters)
- // NODEBOX_FIXED
- core::aabbox3d<f32> fixed;
- // NODEBOX_WALLMOUNTED
- core::aabbox3d<f32> wall_top;
- core::aabbox3d<f32> wall_bottom;
- core::aabbox3d<f32> wall_side; // being at the -X side
-
- NodeBox():
- type(NODEBOX_REGULAR),
- // default is rail-like
- fixed(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
- // default is sign/ladder-like
- wall_top(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2),
- wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
- wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2)
- {}
-};
-
-struct MapNode;
-class NodeMetadata;
-
-struct ContentFeatures
-{
-#ifndef SERVER
- /*
- 0: up
- 1: down
- 2: right
- 3: left
- 4: back
- 5: front
- */
- TileSpec tiles[6];
-
- video::ITexture *inventory_texture;
-
- // Used currently for flowing liquids
- u8 vertex_alpha;
- // Post effect color, drawn when the camera is inside the node.
- video::SColor post_effect_color;
- // Special irrlicht material, used sometimes
- video::SMaterial *special_material;
- video::SMaterial *special_material2;
- AtlasPointer *special_atlas;
-#endif
-
- // List of all block textures that have been used (value is dummy)
- // Used for texture atlas making.
- // Exists on server too for cleaner code in content_mapnode.cpp.
- core::map<std::string, bool> used_texturenames;
-
- // Type of MapNode::param1
- ContentParamType param_type;
- // True for all ground-like things like stone and mud, false for eg. trees
- bool is_ground_content;
- bool light_propagates;
- bool sunlight_propagates;
- u8 solidness; // Used when choosing which face is drawn
- u8 visual_solidness; // When solidness=0, this tells how it looks like
- // This is used for collision detection.
- // Also for general solidness queries.
- bool walkable;
- // Player can point to these
- bool pointable;
- // Player can dig these
- bool diggable;
- // Player can climb these
- bool climbable;
- // Player can build on these
- bool buildable_to;
- // If true, param2 is set to direction when placed. Used for torches.
- // NOTE: the direction format is quite inefficient and should be changed
- bool wall_mounted;
- // If true, node is equivalent to air. Torches are, air is. Water is not.
- // Is used for example to check whether a mud block can have grass on.
- bool air_equivalent;
- // Whether this content type often contains mineral.
- // Used for texture atlas creation.
- // Currently only enabled for CONTENT_STONE.
- bool often_contains_mineral;
-
- // Inventory item string as which the node appears in inventory when dug.
- // Mineral overrides this.
- std::string dug_item;
-
- // Extra dug item and its rarity
- std::string extra_dug_item;
- s32 extra_dug_item_rarity;
-
- // Initial metadata is cloned from this
- NodeMetadata *initial_metadata;
-
- // Whether the node is non-liquid, source liquid or flowing liquid
- enum LiquidType liquid_type;
- // If the content is liquid, this is the flowing version of the liquid.
- content_t liquid_alternative_flowing;
- // If the content is liquid, this is the source version of the liquid.
- content_t liquid_alternative_source;
- // Viscosity for fluid flow, ranging from 1 to 7, with
- // 1 giving almost instantaneous propagation and 7 being
- // the slowest possible
- u8 liquid_viscosity;
-
- // Amount of light the node emits
- u8 light_source;
-
- u32 damage_per_second;
-
- NodeBox selection_box;
-
- MaterialProperties material;
-
- // NOTE: Move relevant properties to here from elsewhere
-
- void reset()
- {
-#ifndef SERVER
- inventory_texture = NULL;
-
- vertex_alpha = 255;
- post_effect_color = video::SColor(0, 0, 0, 0);
- special_material = NULL;
- special_material2 = NULL;
- special_atlas = NULL;
-#endif
- param_type = CPT_NONE;
- is_ground_content = false;
- light_propagates = false;
- sunlight_propagates = false;
- solidness = 2;
- visual_solidness = 0;
- walkable = true;
- pointable = true;
- diggable = true;
- climbable = false;
- buildable_to = false;
- wall_mounted = false;
- air_equivalent = false;
- often_contains_mineral = false;
- dug_item = "";
- initial_metadata = NULL;
- liquid_type = LIQUID_NONE;
- liquid_alternative_flowing = CONTENT_IGNORE;
- liquid_alternative_source = CONTENT_IGNORE;
- liquid_viscosity = 0;
- light_source = 0;
- damage_per_second = 0;
- selection_box = NodeBox();
- material = MaterialProperties();
- }
-
- ContentFeatures()
- {
- reset();
- }
-
- ~ContentFeatures();
-
- /*
- Quickhands for simple materials
- */
-
-#ifdef SERVER
- void setTexture(ITextureSource *tsrc, u16 i, std::string name,
- u8 alpha=255)
- {}
- void setAllTextures(ITextureSource *tsrc, std::string name, u8 alpha=255)
- {}
-#else
- void setTexture(ITextureSource *tsrc,
- u16 i, std::string name, u8 alpha=255);
-
- void setAllTextures(ITextureSource *tsrc,
- std::string name, u8 alpha=255)
- {
- for(u16 i=0; i<6; i++)
- {
- setTexture(tsrc, i, name, alpha);
- }
- // Force inventory texture too
- setInventoryTexture(name, tsrc);
- }
-#endif
-
-#ifndef SERVER
- void setTile(u16 i, const TileSpec &tile)
- {
- tiles[i] = tile;
- }
- void setAllTiles(const TileSpec &tile)
- {
- for(u16 i=0; i<6; i++)
- {
- setTile(i, tile);
- }
- }
-#endif
-
-#ifdef SERVER
- void setInventoryTexture(std::string imgname,
- ITextureSource *tsrc)
- {}
- void setInventoryTextureCube(std::string top,
- std::string left, std::string right, ITextureSource *tsrc)
- {}
-#else
- void setInventoryTexture(std::string imgname, ITextureSource *tsrc);
-
- void setInventoryTextureCube(std::string top,
- std::string left, std::string right, ITextureSource *tsrc);
-#endif
-};
-
-/*
- Call this to access the ContentFeature list
-*/
-ContentFeatures & content_features(content_t i);
-ContentFeatures & content_features(MapNode &n);
-
-/*
- Here is a bunch of DEPRECATED functions.
-*/
-
-/*
- If true, the material allows light propagation and brightness is stored
- in param.
- NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline bool light_propagates_content(content_t m)
-{
- return content_features(m).light_propagates;
-}
-/*
- If true, the material allows lossless sunlight propagation.
- NOTE: It doesn't seem to go through torches regardlessly of this
- NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline bool sunlight_propagates_content(content_t m)
-{
- return content_features(m).sunlight_propagates;
-}
-/*
- On a node-node surface, the material of the node with higher solidness
- is used for drawing.
- 0: Invisible
- 1: Transparent
- 2: Opaque
- NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline u8 content_solidness(content_t m)
-{
- return content_features(m).solidness;
-}
-// Objects collide with walkable contents
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_walkable(content_t m)
-{
- 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
-
#include "exceptions.h"
#include "mapblock.h"
-MapSector::MapSector(Map *parent, v2s16 pos):
+MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
differs_from_disk(false),
m_parent(parent),
m_pos(pos),
+ m_gamedef(gamedef),
m_block_cache(NULL)
{
}
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;
}
ServerMapSector
*/
-ServerMapSector::ServerMapSector(Map *parent, v2s16 pos):
- MapSector(parent, pos)
+ServerMapSector::ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
+ MapSector(parent, pos, gamedef)
{
}
std::istream &is,
Map *parent,
v2s16 p2d,
- core::map<v2s16, MapSector*> & sectors
+ core::map<v2s16, MapSector*> & sectors,
+ IGameDef *gamedef
)
{
/*
}
else
{
- sector = new ServerMapSector(parent, p2d);
+ sector = new ServerMapSector(parent, p2d, gamedef);
sectors.insert(p2d, sector);
}
ClientMapSector
*/
-ClientMapSector::ClientMapSector(Map *parent, v2s16 pos):
- MapSector(parent, pos)
+ClientMapSector::ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
+ MapSector(parent, pos, gamedef)
{
}
class MapBlock;
class Map;
+class IGameDef;
/*
This is an Y-wise stack of MapBlocks.
{
public:
- MapSector(Map *parent, v2s16 pos);
+ MapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
virtual ~MapSector();
virtual u32 getId() const = 0;
Map *m_parent;
// Position on parent (in MapBlock widths)
v2s16 m_pos;
-
+
+ IGameDef *m_gamedef;
+
// Last-used block is cached here for quicker access.
// Be sure to set this to NULL when the cached block is deleted
MapBlock *m_block_cache;
class ServerMapSector : public MapSector
{
public:
- ServerMapSector(Map *parent, v2s16 pos);
+ ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
~ServerMapSector();
u32 getId() const
std::istream &is,
Map *parent,
v2s16 p2d,
- core::map<v2s16, MapSector*> & sectors
+ core::map<v2s16, MapSector*> & sectors,
+ IGameDef *gamedef
);
private:
class ClientMapSector : public MapSector
{
public:
- ClientMapSector(Map *parent, v2s16 pos);
+ ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
~ClientMapSector();
u32 getId() const
#include "materials.h"
#include "mapnode.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
-DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp)
+DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
+ INodeDefManager *nodemgr)
{
assert(tp);
- MaterialProperties &mp = content_features(material).material;
+ const MaterialProperties &mp = nodemgr->get(content).material;
if(mp.diggability == DIGGABLE_NOT)
return DiggingProperties(false, 0, 0);
if(mp.diggability == DIGGABLE_CONSTANT)
};
class ToolDiggingProperties;
+class INodeDefManager;
-DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp);
+DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
+ INodeDefManager *nodemgr);
#endif
--- /dev/null
+/*
+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);
+}
+
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2010-2011 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.
+*/
+
+#ifndef NODEDEF_HEADER
+#define NODEDEF_HEADER
+
+#include "common_irrlicht.h"
+#include <string>
+#include <set>
+#include "mapnode.h"
+#ifndef SERVER
+#include "tile.h"
+#endif
+#include "materials.h" // MaterialProperties
+class ITextureSource;
+
+/*
+ TODO: Rename to nodedef.h
+*/
+
+#if 0
+
+/*
+ Content feature list
+
+ Used for determining properties of MapNodes by content type without
+ storing such properties in the nodes itself.
+*/
+
+/*
+ Initialize content feature table.
+
+ Must be called before accessing the table.
+*/
+void init_contentfeatures(ITextureSource *tsrc);
+
+#endif
+
+enum ContentParamType
+{
+ CPT_NONE,
+ CPT_LIGHT,
+ CPT_MINERAL,
+ // Direction for chests and furnaces and such
+ CPT_FACEDIR_SIMPLE
+};
+
+enum LiquidType
+{
+ LIQUID_NONE,
+ LIQUID_FLOWING,
+ LIQUID_SOURCE
+};
+
+enum NodeBoxType
+{
+ NODEBOX_REGULAR, // Regular block; allows buildable_to
+ NODEBOX_FIXED, // Static separately defined box
+ NODEBOX_WALLMOUNTED, // Box for wall_mounted nodes; (top, bottom, side)
+};
+
+struct NodeBox
+{
+ enum NodeBoxType type;
+ // NODEBOX_REGULAR (no parameters)
+ // NODEBOX_FIXED
+ core::aabbox3d<f32> fixed;
+ // NODEBOX_WALLMOUNTED
+ core::aabbox3d<f32> wall_top;
+ core::aabbox3d<f32> wall_bottom;
+ core::aabbox3d<f32> wall_side; // being at the -X side
+
+ NodeBox():
+ type(NODEBOX_REGULAR),
+ // default is rail-like
+ fixed(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
+ // default is sign/ladder-like
+ wall_top(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2),
+ wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
+ wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2)
+ {}
+};
+
+struct MapNode;
+class NodeMetadata;
+
+struct ContentFeatures
+{
+#ifndef SERVER
+ /*
+ 0: up
+ 1: down
+ 2: right
+ 3: left
+ 4: back
+ 5: front
+ */
+ TileSpec tiles[6];
+
+ video::ITexture *inventory_texture;
+
+ // Used currently for flowing liquids
+ u8 vertex_alpha;
+ // Post effect color, drawn when the camera is inside the node.
+ video::SColor post_effect_color;
+ // Special irrlicht material, used sometimes
+ video::SMaterial *special_material;
+ video::SMaterial *special_material2;
+ AtlasPointer *special_atlas;
+#endif
+
+ // List of all block textures that have been used (value is dummy)
+ // Used for texture atlas making.
+ // Exists on server too for cleaner code in content_mapnode.cpp.
+ std::set<std::string> used_texturenames;
+
+ // Type of MapNode::param1
+ ContentParamType param_type;
+ // True for all ground-like things like stone and mud, false for eg. trees
+ bool is_ground_content;
+ bool light_propagates;
+ bool sunlight_propagates;
+ u8 solidness; // Used when choosing which face is drawn
+ u8 visual_solidness; // When solidness=0, this tells how it looks like
+ // This is used for collision detection.
+ // Also for general solidness queries.
+ bool walkable;
+ // Player can point to these
+ bool pointable;
+ // Player can dig these
+ bool diggable;
+ // Player can climb these
+ bool climbable;
+ // Player can build on these
+ bool buildable_to;
+ // If true, param2 is set to direction when placed. Used for torches.
+ // NOTE: the direction format is quite inefficient and should be changed
+ bool wall_mounted;
+ // If true, node is equivalent to air. Torches are, air is. Water is not.
+ // Is used for example to check whether a mud block can have grass on.
+ bool air_equivalent;
+ // Whether this content type often contains mineral.
+ // Used for texture atlas creation.
+ // Currently only enabled for CONTENT_STONE.
+ bool often_contains_mineral;
+
+ // Inventory item string as which the node appears in inventory when dug.
+ // Mineral overrides this.
+ std::string dug_item;
+
+ // Extra dug item and its rarity
+ std::string extra_dug_item;
+ s32 extra_dug_item_rarity;
+
+ // Initial metadata is cloned from this
+ NodeMetadata *initial_metadata;
+
+ // Whether the node is non-liquid, source liquid or flowing liquid
+ enum LiquidType liquid_type;
+ // If the content is liquid, this is the flowing version of the liquid.
+ content_t liquid_alternative_flowing;
+ // If the content is liquid, this is the source version of the liquid.
+ content_t liquid_alternative_source;
+ // Viscosity for fluid flow, ranging from 1 to 7, with
+ // 1 giving almost instantaneous propagation and 7 being
+ // the slowest possible
+ u8 liquid_viscosity;
+
+ // Amount of light the node emits
+ u8 light_source;
+
+ u32 damage_per_second;
+
+ NodeBox selection_box;
+
+ MaterialProperties material;
+
+ // NOTE: Move relevant properties to here from elsewhere
+
+ void reset()
+ {
+#ifndef SERVER
+ inventory_texture = NULL;
+
+ vertex_alpha = 255;
+ post_effect_color = video::SColor(0, 0, 0, 0);
+ special_material = NULL;
+ special_material2 = NULL;
+ special_atlas = NULL;
+#endif
+ used_texturenames.clear();
+ param_type = CPT_NONE;
+ is_ground_content = false;
+ light_propagates = false;
+ sunlight_propagates = false;
+ solidness = 2;
+ visual_solidness = 0;
+ walkable = true;
+ pointable = true;
+ diggable = true;
+ climbable = false;
+ buildable_to = false;
+ wall_mounted = false;
+ air_equivalent = false;
+ often_contains_mineral = false;
+ dug_item = "";
+ initial_metadata = NULL;
+ liquid_type = LIQUID_NONE;
+ liquid_alternative_flowing = CONTENT_IGNORE;
+ liquid_alternative_source = CONTENT_IGNORE;
+ liquid_viscosity = 0;
+ light_source = 0;
+ damage_per_second = 0;
+ selection_box = NodeBox();
+ material = MaterialProperties();
+ }
+
+ ContentFeatures()
+ {
+ reset();
+ }
+
+ ~ContentFeatures();
+
+ /*
+ Quickhands for simple materials
+ */
+
+#ifdef SERVER
+ void setTexture(ITextureSource *tsrc, u16 i, std::string name,
+ u8 alpha=255)
+ {}
+ void setAllTextures(ITextureSource *tsrc, std::string name, u8 alpha=255)
+ {}
+#else
+ void setTexture(ITextureSource *tsrc,
+ u16 i, std::string name, u8 alpha=255);
+
+ void setAllTextures(ITextureSource *tsrc,
+ std::string name, u8 alpha=255)
+ {
+ for(u16 i=0; i<6; i++)
+ {
+ setTexture(tsrc, i, name, alpha);
+ }
+ // Force inventory texture too
+ setInventoryTexture(name, tsrc);
+ }
+#endif
+
+#ifndef SERVER
+ void setTile(u16 i, const TileSpec &tile)
+ { tiles[i] = tile; }
+ void setAllTiles(const TileSpec &tile)
+ { for(u16 i=0; i<6; i++) setTile(i, tile); }
+#endif
+
+#ifdef SERVER
+ void setInventoryTexture(std::string imgname,
+ ITextureSource *tsrc)
+ {}
+ void setInventoryTextureCube(std::string top,
+ std::string left, std::string right, ITextureSource *tsrc)
+ {}
+#else
+ void setInventoryTexture(std::string imgname, ITextureSource *tsrc);
+
+ void setInventoryTextureCube(std::string top,
+ std::string left, std::string right, ITextureSource *tsrc);
+#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
+{
+public:
+ INodeDefManager(){}
+ virtual ~INodeDefManager(){}
+ // Get node definition
+ virtual const ContentFeatures& get(content_t c) const=0;
+ virtual const ContentFeatures& get(const MapNode &n) const=0;
+};
+
+class IWritableNodeDefManager : public INodeDefManager
+{
+public:
+ IWritableNodeDefManager(){}
+ virtual ~IWritableNodeDefManager(){}
+ virtual IWritableNodeDefManager* clone()=0;
+ // Get node definition
+ virtual const ContentFeatures& get(content_t c) const=0;
+ virtual const ContentFeatures& get(const MapNode &n) const=0;
+
+ // Register node definition
+ virtual void set(content_t c, const ContentFeatures &def)=0;
+ virtual ContentFeatures* getModifiable(content_t c)=0;
+};
+
+// If textures not actually available (server), tsrc can be NULL
+IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc);
+
+
+#endif
+
#endif
#include "main.h" // For g_settings
#include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "environment.h"
+#include "gamedef.h"
-Player::Player():
+Player::Player(IGameDef *gamedef):
touching_ground(false),
in_water(false),
in_water_stable(false),
craftresult_is_preview(true),
hp(20),
peer_id(PEER_ID_INEXISTENT),
+// protected
+ m_gamedef(gamedef),
m_selected_item(0),
m_pitch(0),
m_yaw(0),
inventory.serialize(os);
}
-void Player::deSerialize(std::istream &is, IGameDef *gamedef)
+void Player::deSerialize(std::istream &is)
{
Settings args;
hp = 20;
}
- inventory.deSerialize(is, gamedef);
+ inventory.deSerialize(is, m_gamedef);
}
/*
ServerRemotePlayer
*/
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
+ Player(env->getGameDef()),
+ ServerActiveObject(env, v3f(0,0,0))
+{
+}
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
+ const char *name_):
+ Player(env->getGameDef()),
+ ServerActiveObject(env, pos_)
+{
+ setPosition(pos_);
+ peer_id = peer_id_;
+ updateName(name_);
+}
+
/* ServerActiveObject interface */
InventoryItem* ServerRemotePlayer::getWieldedItem()
#ifndef SERVER
RemotePlayer::RemotePlayer(
+ IGameDef *gamedef,
scene::ISceneNode* parent,
IrrlichtDevice *device,
s32 id):
+ Player(gamedef),
scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id),
m_text(NULL)
{
LocalPlayer
*/
-LocalPlayer::LocalPlayer():
+LocalPlayer::LocalPlayer(IGameDef *gamedef):
+ Player(gamedef),
m_sneak_node(32767,32767,32767),
m_sneak_node_exists(false)
{
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
core::list<CollisionInfo> *collision_info)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
v3f position = getPosition();
v3f oldpos = position;
v3s16 oldpos_i = floatToInt(oldpos, BS);
if(in_water)
{
v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS);
- in_water = content_liquid(map.getNode(pp).getContent());
+ in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
}
// If not in water, the threshold of going in is at lower y
else
{
v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS);
- in_water = content_liquid(map.getNode(pp).getContent());
+ in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
}
}
catch(InvalidPositionException &e)
*/
try{
v3s16 pp = floatToInt(position + v3f(0,0,0), BS);
- in_water_stable = content_liquid(map.getNode(pp).getContent());
+ in_water_stable = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
}
catch(InvalidPositionException &e)
{
*/
try {
- v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
+ v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
- is_climbing = ((content_features(map.getNode(pp).getContent()).climbable ||
- content_features(map.getNode(pp2).getContent()).climbable) && !free_move);
+ is_climbing = ((nodemgr->get(map.getNode(pp).getContent()).climbable ||
+ nodemgr->get(map.getNode(pp2).getContent()).climbable) && !free_move);
}
catch(InvalidPositionException &e)
{
- is_climbing = false;
+ is_climbing = false;
}
/*
bool is_unloaded = false;
try{
// Player collides into walkable nodes
- if(content_walkable(map.getNode(v3s16(x,y,z)).getContent()) == false)
+ if(nodemgr->get(map.getNode(v3s16(x,y,z))).walkable == false)
continue;
}
catch(InvalidPositionException &e)
try{
// The node to be sneaked on has to be walkable
- if(content_walkable(map.getNode(p).getContent()) == false)
+ if(nodemgr->get(map.getNode(p)).walkable == false)
continue;
// And the node above it has to be nonwalkable
- if(content_walkable(map.getNode(p+v3s16(0,1,0)).getContent()) == true)
+ if(nodemgr->get(map.getNode(p+v3s16(0,1,0))).walkable == true)
continue;
}
catch(InvalidPositionException &e)
class Map;
+class IGameDef;
class Player
{
public:
-
- Player();
+ Player(IGameDef *gamedef);
virtual ~Player();
void resetInventory();
deSerialize stops reading exactly at the right point.
*/
void serialize(std::ostream &os);
- void deSerialize(std::istream &is, IGameDef *gamedef);
+ void deSerialize(std::istream &is);
bool touching_ground;
// This oscillates so that the player jumps a bit above the surface
u16 peer_id;
protected:
+ IGameDef *m_gamedef;
+
char m_name[PLAYERNAME_SIZE];
u16 m_selected_item;
f32 m_pitch;
class ServerRemotePlayer : public Player, public ServerActiveObject
{
public:
- ServerRemotePlayer(ServerEnvironment *env):
- ServerActiveObject(env, v3f(0,0,0))
- {
- }
+ ServerRemotePlayer(ServerEnvironment *env);
ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
- const char *name_):
- ServerActiveObject(env, pos_)
- {
- setPosition(pos_);
- peer_id = peer_id_;
- updateName(name_);
- }
+ const char *name_);
+
virtual ~ServerRemotePlayer()
- {
- }
+ {}
virtual bool isLocal() const
- {
- return false;
- }
+ { return false; }
virtual void move(f32 dtime, Map &map, f32 pos_max_d)
{
{
public:
RemotePlayer(
+ IGameDef *gamedef,
scene::ISceneNode* parent=NULL,
IrrlichtDevice *device=NULL,
s32 id=0);
class LocalPlayer : public Player
{
public:
- LocalPlayer();
+ LocalPlayer(IGameDef *gamedef);
virtual ~LocalPlayer();
bool isLocal() const
#include "log.h"
#include "script.h"
#include "scriptapi.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
#include "content_tool.h" // For content_tool_init
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
m_lua(NULL),
m_toolmgr(createToolDefManager()),
+ m_nodemgr(createNodeDefManager(NULL)),
m_thread(this),
m_emergethread(this),
m_time_counter(0),
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
+
+ infostream<<"m_nodemgr="<<m_nodemgr<<std::endl;
// Initialize default tool definitions
content_tool_init(m_toolmgr);
+ // Initialize default node definitions
+ content_mapnode_init(NULL, m_nodemgr);
+
// Initialize scripting
infostream<<"Server: Initializing scripting"<<std::endl;
delete m_env;
delete m_toolmgr;
+ delete m_nodemgr;
// Deinitialize scripting
infostream<<"Server: Deinitializing scripting"<<std::endl;
{
MapNode n = m_env->getMap().getNode(p_under);
// Get mineral
- mineral = n.getMineral();
+ mineral = n.getMineral(m_nodemgr);
// Get material at position
material = n.getContent();
// If not yet cancelled
if(cannot_remove_node == false)
{
// If it's not diggable, do nothing
- if(content_diggable(material) == false)
+ if(m_nodemgr->get(material).diggable == false)
{
infostream<<"Server: Not finishing digging: "
<<"Node not diggable"
ToolDiggingProperties tp =
m_toolmgr->getDiggingProperties(toolname);
DiggingProperties prop =
- getDiggingProperties(material, &tp);
+ getDiggingProperties(material, &tp, m_nodemgr);
if(prop.diggable == false)
{
// If not mineral
if(item == NULL)
{
- std::string &dug_s = content_features(material).dug_item;
+ const std::string &dug_s = m_nodemgr->get(material).dug_item;
if(dug_s != "")
{
std::istringstream is(dug_s, std::ios::binary);
// If not mineral
if(item == NULL)
{
- std::string &extra_dug_s = content_features(material).extra_dug_item;
- s32 extra_rarity = content_features(material).extra_dug_item_rarity;
+ const std::string &extra_dug_s = m_nodemgr->get(material).extra_dug_item;
+ s32 extra_rarity = m_nodemgr->get(material).extra_dug_item_rarity;
if(extra_dug_s != "" && extra_rarity != 0
&& myrand() % extra_rarity == 0)
{
- std::istringstream is(extra_dug_s, std::ios::binary);
+ std::istringstream is(extra_dug_s, std::ios::binary);
item = InventoryItem::deSerialize(is, this);
}
}
if(item != NULL)
{
- // Add a item to inventory
- player->inventory.addItem("main", item);
+ // Add a item to inventory
+ player->inventory.addItem("main", item);
// Send inventory
UpdateCrafting(player->peer_id);
<<" because privileges are "<<getPlayerPrivs(player)
<<std::endl;
- if(content_features(n2).buildable_to == false
+ if(m_nodemgr->get(n2).buildable_to == false
|| no_enough_privs)
{
// Client probably has wrong data.
<<" at "<<PP(p_under)<<std::endl;
// Calculate direction for wall mounted stuff
- if(content_features(n).wall_mounted)
+ if(m_nodemgr->get(n).wall_mounted)
n.param2 = packDir(p_under - p_over);
// Calculate the direction for furnaces and chests and stuff
- if(content_features(n).param_type == CPT_FACEDIR_SIMPLE)
+ if(m_nodemgr->get(n).param_type == CPT_FACEDIR_SIMPLE)
{
v3f playerpos = player->getPosition();
v3f blockpos = intToFloat(p_over, BS) - playerpos;
BroadcastChatMessage(msg);
}
+// IGameDef interface
+// Under envlock
+IToolDefManager* Server::getToolDefManager()
+{
+ return m_toolmgr;
+}
+INodeDefManager* Server::getNodeDefManager()
+{
+ return m_nodemgr;
+}
+ITextureSource* Server::getTextureSource()
+{
+ return NULL;
+}
+
v3f findSpawnPos(ServerMap &map)
{
//return v3f(50,50,50)*BS;
#include "gamedef.h"
struct LuaState;
typedef struct lua_State lua_State;
-class IToolDefManager;
+class IWritableToolDefManager;
+class IWritableNodeDefManager;
/*
Some random functions
// IGameDef interface
// Under envlock
- virtual IToolDefManager* getToolDefManager()
- { return m_toolmgr; }
- virtual INodeDefManager* getNodeDefManager()
- { assert(0); return NULL; } // TODO
+ virtual IToolDefManager* getToolDefManager();
+ virtual INodeDefManager* getNodeDefManager();
+ virtual ITextureSource* getTextureSource();
private:
lua_State *m_lua;
// Tool definition manager
- IToolDefManager *m_toolmgr;
+ IWritableToolDefManager *m_toolmgr;
+
+ // Node definition manager
+ IWritableNodeDefManager *m_nodemgr;
/*
Threads
#include "settings.h"
#include "profiler.h"
#include "log.h"
-#include "mapnode_contentfeatures.h" // For init_contentfeatures
+#include "nodedef.h" // For init_contentfeatures
#include "content_mapnode.h" // For content_mapnode_init
/*
// Initialize stuff
- // Initialize content feature table without textures
- init_contentfeatures(NULL);
- // Initialize mapnode content without textures
- content_mapnode_init(NULL);
-
init_mineral();
/*
#include <sstream>
#include "porting.h"
#include "content_mapnode.h"
+#include "nodedef.h"
#include "mapsector.h"
#include "settings.h"
#include "log.h"
struct TestMapNode
{
- void Run()
+ void Run(INodeDefManager *nodedef)
{
MapNode n;
// Default values
assert(n.getContent() == CONTENT_AIR);
- assert(n.getLight(LIGHTBANK_DAY) == 0);
- assert(n.getLight(LIGHTBANK_NIGHT) == 0);
+ assert(n.getLight(LIGHTBANK_DAY, nodedef) == 0);
+ assert(n.getLight(LIGHTBANK_NIGHT, nodedef) == 0);
// Transparency
n.setContent(CONTENT_AIR);
- assert(n.light_propagates() == true);
+ assert(nodedef->get(n).light_propagates == true);
n.setContent(CONTENT_STONE);
- assert(n.light_propagates() == false);
+ assert(nodedef->get(n).light_propagates == false);
}
};
struct TestVoxelManipulator
{
- void Run()
+ void Run(INodeDefManager *nodedef)
{
/*
VoxelArea
VoxelManipulator v;
- v.print(infostream);
+ v.print(infostream, nodedef);
infostream<<"*** Setting (-1,0,-1)=2 ***"<<std::endl;
v.setNodeNoRef(v3s16(-1,0,-1), MapNode(2));
- v.print(infostream);
+ v.print(infostream, nodedef);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1)));
- v.print(infostream);
+ v.print(infostream, nodedef);
infostream<<"*** Adding area ***"<<std::endl;
v.addArea(a);
- v.print(infostream);
+ v.print(infostream, nodedef);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
-
-#if 0
- /*
- Water stuff
- */
-
- v.clear();
-
- const char *content =
- "#...###### "
- "#...##..## "
- "#........ .."
- "############"
-
- "#...###### "
- "#...##..## "
- "#........# "
- "############"
- ;
-
- v3s16 size(12, 4, 2);
- VoxelArea area(v3s16(0,0,0), size-v3s16(1,1,1));
-
- const char *p = content;
- for(s16 z=0; z<size.Z; z++)
- for(s16 y=size.Y-1; y>=0; y--)
- for(s16 x=0; x<size.X; x++)
- {
- MapNode n;
- //n.pressure = size.Y - y;
- if(*p == '#')
- n.setContent(CONTENT_STONE);
- else if(*p == '.')
- n.setContent(CONTENT_WATER);
- else if(*p == ' ')
- n.setContent(CONTENT_AIR);
- else
- assert(0);
- v.setNode(v3s16(x,y,z), n);
- p++;
- }
-
- v.print(infostream, VOXELPRINT_WATERPRESSURE);
-
- core::map<v3s16, u8> active_nodes;
- v.updateAreaWaterPressure(area, active_nodes);
-
- v.print(infostream, VOXELPRINT_WATERPRESSURE);
-
- //s16 highest_y = -32768;
- /*
- NOTE: These are commented out because this behaviour is changed
- all the time
- */
- //assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
- //assert(highest_y == 3);
- /*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
- //assert(highest_y == 3);*/
-
- active_nodes.clear();
- active_nodes[v3s16(9,1,0)] = 1;
- //v.flowWater(active_nodes, 0, true, 1000);
- v.flowWater(active_nodes, 0, false, 1000);
-
- infostream<<"Final result of flowWater:"<<std::endl;
- v.print(infostream, VOXELPRINT_WATERPRESSURE);
-#endif
-
- //assert(0);
}
};
x.Run();\
}
+#define TESTPARAMS(X, ...)\
+{\
+ X x;\
+ infostream<<"Running " #X <<std::endl;\
+ x.Run(__VA_ARGS__);\
+}
+
void run_tests()
{
DSTACK(__FUNCTION_NAME);
+
+ // Create node definitions
+ IWritableNodeDefManager *nodedef = createNodeDefManager(NULL);
+ content_mapnode_init(NULL, nodedef);
+
infostream<<"run_tests() started"<<std::endl;
TEST(TestUtilities);
TEST(TestSettings);
TEST(TestCompress);
- TEST(TestMapNode);
- TEST(TestVoxelManipulator);
+ TESTPARAMS(TestMapNode, nodedef);
+ TESTPARAMS(TestVoxelManipulator, nodedef);
//TEST(TestMapBlock);
//TEST(TestMapSector);
if(INTERNET_SIMULATOR == false){
#include "log.h"
#include "mapnode.h" // For texture atlas making
#include "mineral.h" // For texture atlas making
-#include "mapnode_contentfeatures.h" // For texture atlas making
+#include "nodedef.h" // For texture atlas making
+#include "gamedef.h"
/*
A cache from texture name to texture path
TextureSource
*/
+class TextureSource : public IWritableTextureSource
+{
+public:
+ TextureSource(IrrlichtDevice *device);
+ ~TextureSource();
+
+ /*
+ Example case:
+ Now, assume a texture with the id 1 exists, and has the name
+ "stone.png^mineral1".
+ Then a random thread calls getTextureId for a texture called
+ "stone.png^mineral1^crack0".
+ ...Now, WTF should happen? Well:
+ - getTextureId strips off stuff recursively from the end until
+ the remaining part is found, or nothing is left when
+ something is stripped out
+
+ But it is slow to search for textures by names and modify them
+ like that?
+ - ContentFeatures is made to contain ids for the basic plain
+ textures
+ - Crack textures can be slow by themselves, but the framework
+ must be fast.
+
+ Example case #2:
+ - Assume a texture with the id 1 exists, and has the name
+ "stone.png^mineral1" and is specified as a part of some atlas.
+ - Now MapBlock::getNodeTile() stumbles upon a node which uses
+ texture id 1, and finds out that NODEMOD_CRACK must be applied
+ with progression=0
+ - It finds out the name of the texture with getTextureName(1),
+ appends "^crack0" to it and gets a new texture id with
+ getTextureId("stone.png^mineral1^crack0")
+
+ */
+
+ /*
+ Gets a texture id from cache or
+ - if main thread, from getTextureIdDirect
+ - if other thread, adds to request queue and waits for main thread
+ */
+ u32 getTextureId(const std::string &name);
+
+ /*
+ Example names:
+ "stone.png"
+ "stone.png^crack2"
+ "stone.png^blit:mineral_coal.png"
+ "stone.png^blit:mineral_coal.png^crack1"
+
+ - If texture specified by name is found from cache, return the
+ cached id.
+ - Otherwise generate the texture, add to cache and return id.
+ Recursion is used to find out the largest found part of the
+ texture and continue based on it.
+
+ The id 0 points to a NULL texture. It is returned in case of error.
+ */
+ u32 getTextureIdDirect(const std::string &name);
+
+ /*
+ Finds out the name of a cached texture.
+ */
+ std::string getTextureName(u32 id);
+
+ /*
+ If texture specified by the name pointed by the id doesn't
+ exist, create it, then return the cached texture.
+
+ Can be called from any thread. If called from some other thread
+ and not found in cache, the call is queued to the main thread
+ for processing.
+ */
+ AtlasPointer getTexture(u32 id);
+
+ AtlasPointer getTexture(const std::string &name)
+ {
+ return getTexture(getTextureId(name));
+ }
+
+ // Gets a separate texture
+ video::ITexture* getTextureRaw(const std::string &name)
+ {
+ AtlasPointer ap = getTexture(name);
+ return ap.atlas;
+ }
+
+ /*
+ Update new texture pointer and texture coordinates to an
+ AtlasPointer based on it's texture id
+ */
+ void updateAP(AtlasPointer &ap);
+
+ /*
+ Build the main texture atlas which contains most of the
+ textures.
+
+ This is called by the constructor.
+ */
+ void buildMainAtlas(class IGameDef *gamedef);
+
+ /*
+ Processes queued texture requests from other threads.
+
+ Shall be called from the main thread.
+ */
+ void processQueue();
+
+private:
+
+ // The id of the thread that is allowed to use irrlicht directly
+ threadid_t m_main_thread;
+ // The irrlicht device
+ IrrlichtDevice *m_device;
+
+ // A texture id is index in this array.
+ // The first position contains a NULL texture.
+ core::array<SourceAtlasPointer> m_atlaspointer_cache;
+ // Maps a texture name to an index in the former.
+ core::map<std::string, u32> m_name_to_id;
+ // The two former containers are behind this mutex
+ JMutex m_atlaspointer_cache_mutex;
+
+ // Main texture atlas. This is filled at startup and is then not touched.
+ video::IImage *m_main_atlas_image;
+ video::ITexture *m_main_atlas_texture;
+
+ // Queued texture fetches (to be processed by the main thread)
+ RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+};
+
+IWritableTextureSource* createTextureSource(IrrlichtDevice *device)
+{
+ return new TextureSource(device);
+}
+
TextureSource::TextureSource(IrrlichtDevice *device):
m_device(device),
m_main_atlas_image(NULL),
// Add a NULL AtlasPointer as the first index, named ""
m_atlaspointer_cache.push_back(SourceAtlasPointer(""));
m_name_to_id[""] = 0;
-
- // Build main texture atlas
- if(g_settings->getBool("enable_texture_atlas"))
- buildMainAtlas();
- else
- infostream<<"Not building texture atlas."<<std::endl;
}
TextureSource::~TextureSource()
return m_atlaspointer_cache[id].a;
}
-void TextureSource::buildMainAtlas()
+void TextureSource::updateAP(AtlasPointer &ap)
{
+ AtlasPointer ap2 = getTexture(ap.id);
+ ap = ap2;
+}
+
+void TextureSource::buildMainAtlas(class IGameDef *gamedef)
+{
+ assert(gamedef->tsrc() == this);
+ INodeDefManager *ndef = gamedef->ndef();
+
infostream<<"TextureSource::buildMainAtlas()"<<std::endl;
//return; // Disable (for testing)
{
if(j == CONTENT_IGNORE || j == CONTENT_AIR)
continue;
- ContentFeatures *f = &content_features(j);
- for(core::map<std::string, bool>::Iterator
- i = f->used_texturenames.getIterator();
- i.atEnd() == false; i++)
+ const ContentFeatures &f = ndef->get(j);
+ for(std::set<std::string>::const_iterator
+ i = f.used_texturenames.begin();
+ i != f.used_texturenames.end(); i++)
{
- std::string name = i.getNode()->getKey();
+ std::string name = *i;
sourcelist[name] = true;
- if(f->often_contains_mineral){
+ if(f.often_contains_mineral){
for(int k=1; k<MINERAL_COUNT; k++){
std::string mineraltexture = mineral_block_texture(k);
std::string fulltexture = name + "^" + mineraltexture;
Add texture to caches
*/
- // Get next id
+ bool reuse_old_id = false;
u32 id = m_atlaspointer_cache.size();
+ // Check old id without fetching a texture
+ core::map<std::string, u32>::Node *n;
+ n = m_name_to_id.find(name);
+ // If it exists, we will replace the old definition
+ if(n){
+ id = n->getValue();
+ reuse_old_id = true;
+ }
+ infostream<<"TextureSource::buildMainAtlas(): "
+ <<"Replacing old AtlasPointer"<<std::endl;
// Create AtlasPointer
AtlasPointer ap(id);
// Create SourceAtlasPointer and add to containers
SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
- m_atlaspointer_cache.push_back(nap);
- m_name_to_id.insert(name, id);
+ if(reuse_old_id)
+ m_atlaspointer_cache[id] = nap;
+ else
+ m_atlaspointer_cache.push_back(nap);
+ m_name_to_id[name] = id;
// Increment position
pos_in_atlas.Y += dim.Height + padding * 2;
#include "utility.h"
#include <string>
+class IGameDef;
+
/*
tile.{h,cpp}: Texture handling stuff.
*/
};
/*
- Implementation (to be used as a no-op on the server)
+ TextureSource creates and caches textures.
*/
+
class ITextureSource
{
public:
{return NULL;}
};
-/*
- Creates and caches textures.
-*/
-class TextureSource : public ITextureSource
+class IWritableTextureSource : public ITextureSource
{
public:
- TextureSource(IrrlichtDevice *device);
- ~TextureSource();
-
- /*
- Processes queued texture requests from other threads.
-
- Shall be called from the main thread.
- */
- void processQueue();
-
- /*
- Example case:
- Now, assume a texture with the id 1 exists, and has the name
- "stone.png^mineral1".
- Then a random thread calls getTextureId for a texture called
- "stone.png^mineral1^crack0".
- ...Now, WTF should happen? Well:
- - getTextureId strips off stuff recursively from the end until
- the remaining part is found, or nothing is left when
- something is stripped out
-
- But it is slow to search for textures by names and modify them
- like that?
- - ContentFeatures is made to contain ids for the basic plain
- textures
- - Crack textures can be slow by themselves, but the framework
- must be fast.
-
- Example case #2:
- - Assume a texture with the id 1 exists, and has the name
- "stone.png^mineral1" and is specified as a part of some atlas.
- - Now MapBlock::getNodeTile() stumbles upon a node which uses
- texture id 1, and finds out that NODEMOD_CRACK must be applied
- with progression=0
- - It finds out the name of the texture with getTextureName(1),
- appends "^crack0" to it and gets a new texture id with
- getTextureId("stone.png^mineral1^crack0")
-
- */
-
- /*
- Gets a texture id from cache or
- - if main thread, from getTextureIdDirect
- - if other thread, adds to request queue and waits for main thread
- */
- u32 getTextureId(const std::string &name);
-
- /*
- Example names:
- "stone.png"
- "stone.png^crack2"
- "stone.png^blit:mineral_coal.png"
- "stone.png^blit:mineral_coal.png^crack1"
-
- - If texture specified by name is found from cache, return the
- cached id.
- - Otherwise generate the texture, add to cache and return id.
- Recursion is used to find out the largest found part of the
- texture and continue based on it.
-
- The id 0 points to a NULL texture. It is returned in case of error.
- */
- u32 getTextureIdDirect(const std::string &name);
-
- /*
- Finds out the name of a cached texture.
- */
- std::string getTextureName(u32 id);
-
- /*
- If texture specified by the name pointed by the id doesn't
- exist, create it, then return the cached texture.
-
- Can be called from any thread. If called from some other thread
- and not found in cache, the call is queued to the main thread
- for processing.
- */
- AtlasPointer getTexture(u32 id);
-
- AtlasPointer getTexture(const std::string &name)
- {
- return getTexture(getTextureId(name));
- }
-
- // Gets a separate texture
- video::ITexture* getTextureRaw(const std::string &name)
- {
- AtlasPointer ap = getTexture(name);
- return ap.atlas;
- }
-
-private:
- /*
- Build the main texture atlas which contains most of the
- textures.
-
- This is called by the constructor.
- */
- void buildMainAtlas();
-
- // The id of the thread that is allowed to use irrlicht directly
- threadid_t m_main_thread;
- // The irrlicht device
- IrrlichtDevice *m_device;
-
- // A texture id is index in this array.
- // The first position contains a NULL texture.
- core::array<SourceAtlasPointer> m_atlaspointer_cache;
- // Maps a texture name to an index in the former.
- core::map<std::string, u32> m_name_to_id;
- // The two former containers are behind this mutex
- JMutex m_atlaspointer_cache_mutex;
-
- // Main texture atlas. This is filled at startup and is then not touched.
- video::IImage *m_main_atlas_image;
- video::ITexture *m_main_atlas_texture;
+ IWritableTextureSource(){}
+ virtual ~IWritableTextureSource(){}
+ virtual u32 getTextureId(const std::string &name){return 0;}
+ virtual u32 getTextureIdDirect(const std::string &name){return 0;}
+ virtual std::string getTextureName(u32 id){return "";}
+ virtual AtlasPointer getTexture(u32 id){return AtlasPointer(0);}
+ virtual AtlasPointer getTexture(const std::string &name)
+ {return AtlasPointer(0);}
+ virtual video::ITexture* getTextureRaw(const std::string &name)
+ {return NULL;}
- // Queued texture fetches (to be processed by the main thread)
- RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+ virtual void updateAP(AtlasPointer &ap)=0;
+ virtual void buildMainAtlas(class IGameDef *gamedef)=0;
+ virtual void processQueue()=0;
};
+IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
+
enum MaterialType{
MATERIAL_ALPHA_NONE,
MATERIAL_ALPHA_VERTEX,
+++ /dev/null
-/*
-Minetest-c55
-Copyright (C) 2011 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 "tool.h"
-#include "irrlichttypes.h"
-#include "log.h"
-#include <ostream>
-
-class CToolDefManager: public IToolDefManager
-{
-public:
- virtual ~CToolDefManager()
- {
- for(core::map<std::string, ToolDefinition*>::Iterator
- i = m_tool_definitions.getIterator();
- i.atEnd() == false; i++){
- delete i.getNode()->getValue();
- }
- }
- virtual bool registerTool(std::string toolname, const ToolDefinition &def)
- {
- infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
- core::map<std::string, ToolDefinition*>::Node *n;
- n = m_tool_definitions.find(toolname);
- if(n != NULL){
- errorstream<<"registerTool: registering tool \""<<toolname
- <<"\" failed: name is already registered"<<std::endl;
- return false;
- }
- m_tool_definitions[toolname] = new ToolDefinition(def);
- return true;
- }
- virtual ToolDefinition* getToolDefinition(const std::string &toolname)
- {
- 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:
- // Key is name
- core::map<std::string, ToolDefinition*> m_tool_definitions;
-};
-
-IToolDefManager* createToolDefManager()
-{
- return new CToolDefManager();
-}
-
+++ /dev/null
-/*
-Minetest-c55
-Copyright (C) 2011 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.
-*/
-
-#ifndef TOOL_HEADER
-#define TOOL_HEADER
-
-#include <string>
-
-struct ToolDiggingProperties
-{
- // time = basetime + sum(feature here * feature in MaterialProperties)
- float basetime;
- float dt_weight;
- float dt_crackiness;
- float dt_crumbliness;
- float dt_cuttability;
- float basedurability;
- float dd_weight;
- float dd_crackiness;
- float dd_crumbliness;
- float dd_cuttability;
-
- ToolDiggingProperties(float a=0.75, float b=0, float c=0, float d=0, float e=0,
- float f=50, float g=0, float h=0, float i=0, float j=0):
- basetime(a),
- dt_weight(b),
- dt_crackiness(c),
- dt_crumbliness(d),
- dt_cuttability(e),
- basedurability(f),
- dd_weight(g),
- dd_crackiness(h),
- dd_crumbliness(i),
- dd_cuttability(j)
- {}
-};
-
-struct ToolDefinition
-{
- std::string imagename;
- ToolDiggingProperties properties;
-
- ToolDefinition(){}
- ToolDefinition(const std::string &imagename_,
- ToolDiggingProperties properties_):
- imagename(imagename_),
- properties(properties_)
- {}
-};
-
-class IToolDefManager
-{
-public:
- IToolDefManager(){}
- virtual ~IToolDefManager(){}
- virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
- virtual ToolDefinition* getToolDefinition(const std::string &toolname)=0;
- virtual std::string getImagename(const std::string &toolname)=0;
- virtual ToolDiggingProperties getDiggingProperties(
- const std::string &toolname)=0;
-};
-
-IToolDefManager* createToolDefManager();
-
-#endif
-
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2011 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 "tooldef.h"
+#include "irrlichttypes.h"
+#include "log.h"
+#include <ostream>
+
+class CToolDefManager: public IWritableToolDefManager
+{
+public:
+ virtual ~CToolDefManager()
+ {
+ for(core::map<std::string, ToolDefinition*>::Iterator
+ i = m_tool_definitions.getIterator();
+ i.atEnd() == false; i++){
+ 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)
+ {
+ infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
+ core::map<std::string, ToolDefinition*>::Node *n;
+ n = m_tool_definitions.find(toolname);
+ if(n != NULL){
+ errorstream<<"registerTool: registering tool \""<<toolname
+ <<"\" failed: name is already registered"<<std::endl;
+ return false;
+ }
+ m_tool_definitions[toolname] = new ToolDefinition(def);
+ return true;
+ }
+private:
+ // Key is name
+ core::map<std::string, ToolDefinition*> m_tool_definitions;
+};
+
+IWritableToolDefManager* createToolDefManager()
+{
+ return new CToolDefManager();
+}
+
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2011 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.
+*/
+
+#ifndef TOOLDEF_HEADER
+#define TOOLDEF_HEADER
+
+#include <string>
+
+/*
+ TODO: Rename to tooldef.h
+*/
+
+struct ToolDiggingProperties
+{
+ // time = basetime + sum(feature here * feature in MaterialProperties)
+ float basetime;
+ float dt_weight;
+ float dt_crackiness;
+ float dt_crumbliness;
+ float dt_cuttability;
+ float basedurability;
+ float dd_weight;
+ float dd_crackiness;
+ float dd_crumbliness;
+ float dd_cuttability;
+
+ ToolDiggingProperties(float a=0.75, float b=0, float c=0, float d=0, float e=0,
+ float f=50, float g=0, float h=0, float i=0, float j=0):
+ basetime(a),
+ dt_weight(b),
+ dt_crackiness(c),
+ dt_crumbliness(d),
+ dt_cuttability(e),
+ basedurability(f),
+ dd_weight(g),
+ dd_crackiness(h),
+ dd_crumbliness(i),
+ dd_cuttability(j)
+ {}
+};
+
+struct ToolDefinition
+{
+ std::string imagename;
+ ToolDiggingProperties properties;
+
+ ToolDefinition(){}
+ ToolDefinition(const std::string &imagename_,
+ ToolDiggingProperties properties_):
+ imagename(imagename_),
+ properties(properties_)
+ {}
+};
+
+class IToolDefManager
+{
+public:
+ IToolDefManager(){}
+ virtual ~IToolDefManager(){}
+ virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
+ virtual std::string getImagename(const std::string &toolname) const =0;
+ virtual ToolDiggingProperties getDiggingProperties(
+ const std::string &toolname) const =0;
+};
+
+class IWritableToolDefManager : public IToolDefManager
+{
+public:
+ IWritableToolDefManager(){}
+ virtual ~IWritableToolDefManager(){}
+ virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
+ virtual std::string getImagename(const std::string &toolname) const =0;
+ virtual ToolDiggingProperties getDiggingProperties(
+ const std::string &toolname) const =0;
+
+ virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
+};
+
+IWritableToolDefManager* createToolDefManager();
+
+#endif
+
#include "map.h"
#include "utility.h" // For TimeTaker
#include "gettime.h"
-#include "content_mapnode.h"
+#include "nodedef.h"
/*
Debug stuff
m_flags = NULL;
}
-void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
+void VoxelManipulator::print(std::ostream &o, INodeDefManager *nodemgr,
+ VoxelPrintMode mode)
{
v3s16 em = m_area.getExtent();
v3s16 of = m_area.MinEdge;
}
else if(mode == VOXELPRINT_WATERPRESSURE)
{
- if(m == CONTENT_WATER)
+ if(nodemgr->get(m).isLiquid())
{
c = 'w';
if(pr <= 9)
}
void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
- core::map<v3s16, bool> & light_sources)
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr)
{
v3s16 dirs[6] = {
v3s16(0,0,1), // back
If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node)
*/
- if(n2.getLight(bank) < oldlight)
+ if(n2.getLight(bank, nodemgr) < oldlight)
{
/*
And the neighbor is transparent and it has some light
*/
- if(n2.light_propagates() && n2.getLight(bank) != 0)
+ if(nodemgr->get(n2).light_propagates && n2.getLight(bank, nodemgr) != 0)
{
/*
Set light to 0 and add to queue
*/
- u8 current_light = n2.getLight(bank);
- n2.setLight(bank, 0);
+ u8 current_light = n2.getLight(bank, nodemgr);
+ n2.setLight(bank, 0, nodemgr);
- unspreadLight(bank, n2pos, current_light, light_sources);
+ unspreadLight(bank, n2pos, current_light, light_sources, nodemgr);
/*
Remove from light_sources if it is there
*/
void VoxelManipulator::unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes,
- core::map<v3s16, bool> & light_sources)
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr)
{
if(from_nodes.size() == 0)
return;
u8 oldlight = j.getNode()->getValue();
- unspreadLight(bank, pos, oldlight, light_sources);
+ unspreadLight(bank, pos, oldlight, light_sources, nodemgr);
}
}
#endif
If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node)
*/
- if(n2.getLight(bank) < oldlight)
+ if(n2.getLight(bank, nodemgr) < oldlight)
{
/*
And the neighbor is transparent and it has some light
*/
- if(n2.light_propagates() && n2.getLight(bank) != 0)
+ if(nodemgr->get(n2).light_propagates && n2.getLight(bank, nodemgr) != 0)
{
/*
Set light to 0 and add to queue
*/
- u8 current_light = n2.getLight(bank);
+ u8 current_light = n2.getLight(bank, nodemgr);
n2.setLight(bank, 0);
unlighted_nodes.insert(n2pos, current_light);
}
#endif
-void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
+void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p,
+ INodeDefManager *nodemgr)
{
const v3s16 dirs[6] = {
v3s16(0,0,1), // back
MapNode &n = m_data[i];
- u8 oldlight = n.getLight(bank);
+ u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors
If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn)
*/
- if(n2.getLight(bank) > undiminish_light(oldlight))
+ if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
{
- spreadLight(bank, n2pos);
+ spreadLight(bank, n2pos, nodemgr);
}
/*
If the neighbor is dimmer than how much light this node
would spread on it, add to list
*/
- if(n2.getLight(bank) < newlight)
+ if(n2.getLight(bank, nodemgr) < newlight)
{
- if(n2.light_propagates())
+ if(nodemgr->get(n2).light_propagates)
{
- n2.setLight(bank, newlight);
- spreadLight(bank, n2pos);
+ n2.setLight(bank, newlight, nodemgr);
+ spreadLight(bank, n2pos, nodemgr);
}
}
}
goes on recursively.
*/
void VoxelManipulator::spreadLight(enum LightBank bank,
- core::map<v3s16, bool> & from_nodes)
+ core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr)
{
const v3s16 dirs[6] = {
v3s16(0,0,1), // back
MapNode &n = m_data[i];
- u8 oldlight = n.getLight(bank);
+ u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors
If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn)
*/
- if(n2.getLight(bank) > undiminish_light(oldlight))
+ if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
{
lighted_nodes.insert(n2pos, true);
}
If the neighbor is dimmer than how much light this node
would spread on it, add to list
*/
- if(n2.getLight(bank) < newlight)
+ if(n2.getLight(bank, nodemgr) < newlight)
{
- if(n2.light_propagates())
+ if(nodemgr->get(n2).light_propagates)
{
- n2.setLight(bank, newlight);
+ n2.setLight(bank, newlight, nodemgr);
lighted_nodes.insert(n2pos, true);
}
}
<<std::endl;*/
if(lighted_nodes.size() > 0)
- spreadLight(bank, lighted_nodes);
+ spreadLight(bank, lighted_nodes, nodemgr);
}
#endif
#include "debug.h"
#include "mapnode.h"
+class INodeDefManager;
+
// For VC++
#undef min
#undef max
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 clearFlag(u8 flag);
void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
- core::map<v3s16, bool> & light_sources);
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
void unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes,
- core::map<v3s16, bool> & light_sources);
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
- void spreadLight(enum LightBank bank, v3s16 p);
+ void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
void spreadLight(enum LightBank bank,
- core::map<v3s16, bool> & from_nodes);
+ core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr);
/*
Virtual functions