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