GameDef compiles

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

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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++)

View File

@ -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

View File

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

View File

@ -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];

View File

@ -159,8 +159,9 @@ void ItemSAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
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);

View File

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

View File

@ -17,8 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class IToolDefManager;
class IWritableToolDefManager;
// Add default tools to manager
void content_tool_init(IToolDefManager *mgr);
void content_tool_init(IWritableToolDefManager *mgr);

View File

@ -30,9 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"
#include "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)

View File

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

View File

@ -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);
IWritableTextureSource *tsrc = createTextureSource(device);
// Create node definition manager
IWritableNodeDefManager *nodedef = createNodeDefManager(tsrc);
// 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);
// 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;
}

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

@ -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

View File

@ -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

View File

@ -1,150 +0,0 @@
/*
Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "mapnode_contentfeatures.h"
#include "main.h" // For g_settings
#include "nodemetadata.h"
#ifndef SERVER
#include "tile.h"
#endif
struct ContentFeatures g_content_features[MAX_CONTENT+1];
/*
Initialize content feature table.
Must be called before accessing the table.
*/
void init_contentfeatures(ITextureSource *tsrc)
{
#ifndef SERVER
/*
Set initial material type to same in all tiles, so that the
same material can be used in more stuff.
This is set according to the leaves because they are the only
differing material to which all materials can be changed to
get this optimization.
*/
u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
/*if(new_style_leaves)
initial_material_type = MATERIAL_ALPHA_SIMPLE;
else
initial_material_type = MATERIAL_ALPHA_NONE;*/
for(u16 i=0; i<MAX_CONTENT+1; i++)
{
ContentFeatures *f = &g_content_features[i];
// Re-initialize
f->reset();
for(u16 j=0; j<6; j++)
f->tiles[j].material_type = initial_material_type;
}
#endif
/*
Initially set every block to be shown as an unknown block.
Don't touch CONTENT_IGNORE or CONTENT_AIR.
*/
for(u16 i=0; i<MAX_CONTENT+1; i++)
{
if(i == CONTENT_IGNORE || i == CONTENT_AIR)
continue;
ContentFeatures *f = &g_content_features[i];
f->setAllTextures(tsrc, "unknown_block.png");
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
}
// Make CONTENT_IGNORE to not block the view when occlusion culling
content_features(CONTENT_IGNORE).solidness = 0;
}
ContentFeatures::~ContentFeatures()
{
delete initial_metadata;
#ifndef SERVER
delete special_material;
delete special_atlas;
#endif
}
#ifndef SERVER
void ContentFeatures::setTexture(ITextureSource *tsrc,
u16 i, std::string name, u8 alpha)
{
used_texturenames[name] = true;
if(tsrc)
{
tiles[i].texture = tsrc->getTexture(name);
}
if(alpha != 255)
{
tiles[i].alpha = alpha;
tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
}
if(inventory_texture == NULL)
setInventoryTexture(name, tsrc);
}
void ContentFeatures::setInventoryTexture(std::string imgname,
ITextureSource *tsrc)
{
if(tsrc == NULL)
return;
imgname += "^[forcesingle";
inventory_texture = tsrc->getTextureRaw(imgname);
}
void ContentFeatures::setInventoryTextureCube(std::string top,
std::string left, std::string right, ITextureSource *tsrc)
{
if(tsrc == NULL)
return;
str_replace_char(top, '^', '&');
str_replace_char(left, '^', '&');
str_replace_char(right, '^', '&');
std::string imgname_full;
imgname_full += "[inventorycube{";
imgname_full += top;
imgname_full += "{";
imgname_full += left;
imgname_full += "{";
imgname_full += right;
inventory_texture = tsrc->getTextureRaw(imgname_full);
}
#endif
ContentFeatures & content_features(content_t i)
{
return g_content_features[i];
}
ContentFeatures & content_features(MapNode &n)
{
return content_features(n.getContent());
}

View File

@ -23,10 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "exceptions.h"
#include "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)
{
}

View File

@ -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

View File

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

View File

@ -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

175
src/nodedef.cpp Normal file
View File

@ -0,0 +1,175 @@
/*
Minetest-c55
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "nodedef.h"
#include "main.h" // For g_settings
#include "nodemetadata.h"
#ifndef SERVER
#include "tile.h"
#endif
#include "log.h"
ContentFeatures::~ContentFeatures()
{
delete initial_metadata;
#ifndef SERVER
delete special_material;
delete special_atlas;
#endif
}
#ifndef SERVER
void ContentFeatures::setTexture(ITextureSource *tsrc,
u16 i, std::string name, u8 alpha)
{
used_texturenames.insert(name);
if(tsrc)
{
tiles[i].texture = tsrc->getTexture(name);
}
if(alpha != 255)
{
tiles[i].alpha = alpha;
tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
}
if(inventory_texture == NULL)
setInventoryTexture(name, tsrc);
}
void ContentFeatures::setInventoryTexture(std::string imgname,
ITextureSource *tsrc)
{
if(tsrc == NULL)
return;
imgname += "^[forcesingle";
inventory_texture = tsrc->getTextureRaw(imgname);
}
void ContentFeatures::setInventoryTextureCube(std::string top,
std::string left, std::string right, ITextureSource *tsrc)
{
if(tsrc == NULL)
return;
str_replace_char(top, '^', '&');
str_replace_char(left, '^', '&');
str_replace_char(right, '^', '&');
std::string imgname_full;
imgname_full += "[inventorycube{";
imgname_full += top;
imgname_full += "{";
imgname_full += left;
imgname_full += "{";
imgname_full += right;
inventory_texture = tsrc->getTextureRaw(imgname_full);
}
#endif
class CNodeDefManager: public IWritableNodeDefManager
{
public:
CNodeDefManager(ITextureSource *tsrc)
{
#ifndef SERVER
/*
Set initial material type to same in all tiles, so that the
same material can be used in more stuff.
This is set according to the leaves because they are the only
differing material to which all materials can be changed to
get this optimization.
*/
u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
/*if(new_style_leaves)
initial_material_type = MATERIAL_ALPHA_SIMPLE;
else
initial_material_type = MATERIAL_ALPHA_NONE;*/
for(u16 i=0; i<=MAX_CONTENT; i++)
{
ContentFeatures *f = &m_content_features[i];
// Re-initialize
f->reset();
for(u16 j=0; j<6; j++)
f->tiles[j].material_type = initial_material_type;
}
#endif
/*
Initially set every block to be shown as an unknown block.
Don't touch CONTENT_IGNORE or CONTENT_AIR.
*/
for(u16 i=0; i<=MAX_CONTENT; i++)
{
if(i == CONTENT_IGNORE || i == CONTENT_AIR)
continue;
ContentFeatures *f = &m_content_features[i];
f->setAllTextures(tsrc, "unknown_block.png");
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
}
// Make CONTENT_IGNORE to not block the view when occlusion culling
m_content_features[CONTENT_IGNORE].solidness = 0;
}
virtual ~CNodeDefManager()
{
}
virtual IWritableNodeDefManager* clone()
{
CNodeDefManager *mgr = new CNodeDefManager(NULL);
for(u16 i=0; i<=MAX_CONTENT; i++)
{
mgr->set(i, get(i));
}
return mgr;
}
virtual const ContentFeatures& get(content_t c) const
{
assert(c <= MAX_CONTENT);
return m_content_features[c];
}
virtual const ContentFeatures& get(const MapNode &n) const
{
return get(n.getContent());
}
// Writable
virtual void set(content_t c, const ContentFeatures &def)
{
infostream<<"registerNode: registering content \""<<c<<"\""<<std::endl;
assert(c <= MAX_CONTENT);
m_content_features[c] = def;
}
virtual ContentFeatures* getModifiable(content_t c)
{
assert(c <= MAX_CONTENT);
return &m_content_features[c];
}
private:
ContentFeatures m_content_features[MAX_CONTENT+1];
};
IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc)
{
return new CNodeDefManager(tsrc);
}

View File

@ -17,11 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#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"
@ -29,6 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "materials.h" // MaterialProperties
class ITextureSource;
/*
TODO: Rename to nodedef.h
*/
#if 0
/*
Content feature list
@ -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
/*
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);
}
};
/*
Call this to access the ContentFeature list
*/
ContentFeatures & content_features(content_t i);
ContentFeatures & content_features(MapNode &n);
class INodeDefManager
{
public:
INodeDefManager(){}
virtual ~INodeDefManager(){}
// Get node definition
virtual const ContentFeatures& get(content_t c) const=0;
virtual const ContentFeatures& get(const MapNode &n) const=0;
};
/*
Here is a bunch of DEPRECATED functions.
*/
class IWritableNodeDefManager : public INodeDefManager
{
public:
IWritableNodeDefManager(){}
virtual ~IWritableNodeDefManager(){}
virtual IWritableNodeDefManager* clone()=0;
// Get node definition
virtual const ContentFeatures& get(content_t c) const=0;
virtual const ContentFeatures& get(const MapNode &n) const=0;
// Register node definition
virtual void set(content_t c, const ContentFeatures &def)=0;
virtual ContentFeatures* getModifiable(content_t c)=0;
};
/*
If true, the material allows light propagation and brightness is stored
in param.
NOTE: Don't use, use "content_features(m).whatever" instead
*/
inline bool light_propagates_content(content_t m)
{
return content_features(m).light_propagates;
}
/*
If true, the material allows lossless sunlight propagation.
NOTE: It doesn't seem to go through torches regardlessly of this
NOTE: Don't use, use "content_features(m).whatever" instead
*/
inline bool sunlight_propagates_content(content_t m)
{
return content_features(m).sunlight_propagates;
}
/*
On a node-node surface, the material of the node with higher solidness
is used for drawing.
0: Invisible
1: Transparent
2: Opaque
NOTE: Don't use, use "content_features(m).whatever" instead
*/
inline u8 content_solidness(content_t m)
{
return content_features(m).solidness;
}
// Objects collide with walkable contents
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_walkable(content_t m)
{
return content_features(m).walkable;
}
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_liquid(content_t m)
{
return content_features(m).liquid_type != LIQUID_NONE;
}
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_flowing_liquid(content_t m)
{
return content_features(m).liquid_type == LIQUID_FLOWING;
}
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_liquid_source(content_t m)
{
return content_features(m).liquid_type == LIQUID_SOURCE;
}
// CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
// CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
// NOTE: Don't use, use "content_features(m).whatever" instead
inline content_t make_liquid_flowing(content_t m)
{
u8 c = content_features(m).liquid_alternative_flowing;
assert(c != CONTENT_IGNORE);
return c;
}
// Pointable contents can be pointed to in the map
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_pointable(content_t m)
{
return content_features(m).pointable;
}
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_diggable(content_t m)
{
return content_features(m).diggable;
}
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_buildable_to(content_t m)
{
return content_features(m).buildable_to;
}
// If textures not actually available (server), tsrc can be NULL
IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc);
#endif

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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){

View File

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

View File

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

View File

@ -17,12 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#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,6 +33,35 @@ public:
delete i.getNode()->getValue();
}
}
virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const
{
core::map<std::string, ToolDefinition*>::Node *n;
n = m_tool_definitions.find(toolname);
if(n == NULL)
return NULL;
return n->getValue();
}
virtual std::string getImagename(const std::string &toolname) const
{
const ToolDefinition *def = getToolDefinition(toolname);
if(def == NULL)
return "";
return def->imagename;
}
virtual ToolDiggingProperties getDiggingProperties(
const std::string &toolname) const
{
const ToolDefinition *def = getToolDefinition(toolname);
// If tool does not exist, just return an impossible
if(def == NULL){
// If tool does not exist, try empty name
const ToolDefinition *def = getToolDefinition("");
if(def == NULL) // If that doesn't exist either, return default
return ToolDiggingProperties();
return def->properties;
}
return def->properties;
}
virtual bool registerTool(std::string toolname, const ToolDefinition &def)
{
infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
@ -46,41 +75,12 @@ public:
m_tool_definitions[toolname] = new ToolDefinition(def);
return true;
}
virtual ToolDefinition* getToolDefinition(const std::string &toolname)
{
core::map<std::string, ToolDefinition*>::Node *n;
n = m_tool_definitions.find(toolname);
if(n == NULL)
return NULL;
return n->getValue();
}
virtual std::string getImagename(const std::string &toolname)
{
ToolDefinition *def = getToolDefinition(toolname);
if(def == NULL)
return "";
return def->imagename;
}
virtual ToolDiggingProperties getDiggingProperties(
const std::string &toolname)
{
ToolDefinition *def = getToolDefinition(toolname);
// If tool does not exist, just return an impossible
if(def == NULL){
// If tool does not exist, try empty name
ToolDefinition *def = getToolDefinition("");
if(def == NULL) // If that doesn't exist either, return default
return ToolDiggingProperties();
return def->properties;
}
return def->properties;
}
private:
// Key is name
core::map<std::string, ToolDefinition*> m_tool_definitions;
};
IToolDefManager* createToolDefManager()
IWritableToolDefManager* createToolDefManager()
{
return new CToolDefManager();
}

View File

@ -17,11 +17,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#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)=0;
const std::string &toolname) const =0;
};
IToolDefManager* createToolDefManager();
class IWritableToolDefManager : public IToolDefManager
{
public:
IWritableToolDefManager(){}
virtual ~IWritableToolDefManager(){}
virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
virtual std::string getImagename(const std::string &toolname) const =0;
virtual ToolDiggingProperties getDiggingProperties(
const std::string &toolname) const =0;
virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
};
IWritableToolDefManager* createToolDefManager();
#endif

View File

@ -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

View File

@ -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