mirror of
https://github.com/minetest/minetest.git
synced 2024-08-19 21:14:15 +02:00
GameDef compiles
This commit is contained in:
parent
abceeee92f
commit
c6fd2986d4
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
26
src/client.h
26
src/client.h
@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "gamedef.h"
|
||||
|
||||
struct MeshMakeData;
|
||||
class IGameDef;
|
||||
class IWritableToolDefManager;
|
||||
class IWritableNodeDefManager;
|
||||
|
||||
class ClientNotReadyException : public BaseException
|
||||
{
|
||||
@ -99,8 +102,8 @@ class MeshUpdateThread : public SimpleThread
|
||||
{
|
||||
public:
|
||||
|
||||
MeshUpdateThread(ITextureSource *tsrc):
|
||||
m_tsrc(tsrc)
|
||||
MeshUpdateThread(IGameDef *gamedef):
|
||||
m_gamedef(gamedef)
|
||||
{
|
||||
}
|
||||
|
||||
@ -110,7 +113,7 @@ public:
|
||||
|
||||
MutexedQueue<MeshUpdateResult> m_queue_out;
|
||||
|
||||
ITextureSource *m_tsrc;
|
||||
IGameDef *m_gamedef;
|
||||
};
|
||||
|
||||
enum ClientEventType
|
||||
@ -155,8 +158,9 @@ public:
|
||||
const char *playername,
|
||||
std::string password,
|
||||
MapDrawControl &control,
|
||||
ITextureSource *tsrc,
|
||||
IToolDefManager *toolmgr
|
||||
IWritableTextureSource *tsrc,
|
||||
IWritableToolDefManager *tooldef,
|
||||
IWritableNodeDefManager *nodedef
|
||||
);
|
||||
|
||||
~Client();
|
||||
@ -311,10 +315,9 @@ public:
|
||||
|
||||
// IGameDef interface
|
||||
// Under envlock
|
||||
virtual IToolDefManager* getToolDefManager()
|
||||
{ return m_toolmgr; }
|
||||
virtual INodeDefManager* getNodeDefManager()
|
||||
{ assert(0); return NULL; } // TODO
|
||||
virtual IToolDefManager* getToolDefManager();
|
||||
virtual INodeDefManager* getNodeDefManager();
|
||||
virtual ITextureSource* getTextureSource();
|
||||
|
||||
private:
|
||||
|
||||
@ -338,8 +341,9 @@ private:
|
||||
float m_ignore_damage_timer; // Used after server moves player
|
||||
IntervalLimiter m_map_timer_and_unload_interval;
|
||||
|
||||
ITextureSource *m_tsrc;
|
||||
IToolDefManager *m_toolmgr;
|
||||
IWritableTextureSource *m_tsrc;
|
||||
IWritableToolDefManager *m_tooldef;
|
||||
IWritableNodeDefManager *m_nodedef;
|
||||
MeshUpdateThread m_mesh_update_thread;
|
||||
ClientEnvironment m_env;
|
||||
con::Connection m_con;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
47
src/game.cpp
47
src/game.cpp
@ -44,12 +44,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
// Needed for determining pointing to nodes
|
||||
#include "mapnode_contentfeatures.h"
|
||||
#include "nodedef.h"
|
||||
#include "nodemetadata.h"
|
||||
#include "main.h" // For g_settings
|
||||
#include "content_mapnode.h" // For content_mapnode_init
|
||||
#include "tool.h"
|
||||
#include "content_tool.h" // For content_tool_init
|
||||
#include "tooldef.h"
|
||||
#include "content_tool.h" // Default tools
|
||||
#include "content_mapnode.h" // Default nodes
|
||||
|
||||
/*
|
||||
Setting this to 1 enables a special camera mode that forces
|
||||
@ -321,7 +322,7 @@ void getPointedNode(Client *client, v3f player_position,
|
||||
try
|
||||
{
|
||||
n = client->getNode(v3s16(x,y,z));
|
||||
if(content_pointable(n.getContent()) == false)
|
||||
if(client->getNodeDefManager()->get(n).pointable == false)
|
||||
continue;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
@ -343,7 +344,7 @@ void getPointedNode(Client *client, v3f player_position,
|
||||
v3s16(-1,0,0), // left
|
||||
};
|
||||
|
||||
ContentFeatures &f = content_features(n);
|
||||
const ContentFeatures &f = client->getNodeDefManager()->get(n);
|
||||
|
||||
if(f.selection_box.type == NODEBOX_FIXED)
|
||||
{
|
||||
@ -592,20 +593,17 @@ void the_game(
|
||||
|
||||
draw_load_screen(L"Loading...", driver, font);
|
||||
|
||||
// Create tool manager
|
||||
IToolDefManager *toolmgr = createToolDefManager();
|
||||
|
||||
// Create tool definition manager
|
||||
IWritableToolDefManager *tooldef = createToolDefManager();
|
||||
// Create texture source
|
||||
TextureSource *tsrc = new TextureSource(device);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
164
src/map.cpp
164
src/map.cpp
@ -37,7 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
#include "profiler.h"
|
||||
#include "mapnode_contentfeatures.h"
|
||||
#include "nodedef.h"
|
||||
#include "gamedef.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
@ -234,6 +235,8 @@ void Map::unspreadLight(enum LightBank bank,
|
||||
core::map<v3s16, bool> & light_sources,
|
||||
core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
v3s16 dirs[6] = {
|
||||
v3s16(0,0,1), // back
|
||||
v3s16(0,1,0), // top
|
||||
@ -330,19 +333,20 @@ void Map::unspreadLight(enum LightBank bank,
|
||||
If the neighbor is dimmer than what was specified
|
||||
as oldlight (the light of the previous node)
|
||||
*/
|
||||
if(n2.getLight(bank) < oldlight)
|
||||
if(n2.getLight(bank, nodemgr) < oldlight)
|
||||
{
|
||||
/*
|
||||
And the neighbor is transparent and it has some light
|
||||
*/
|
||||
if(n2.light_propagates() && n2.getLight(bank) != 0)
|
||||
if(nodemgr->get(n2).light_propagates
|
||||
&& n2.getLight(bank, nodemgr) != 0)
|
||||
{
|
||||
/*
|
||||
Set light to 0 and add to queue
|
||||
*/
|
||||
|
||||
u8 current_light = n2.getLight(bank);
|
||||
n2.setLight(bank, 0);
|
||||
u8 current_light = n2.getLight(bank, nodemgr);
|
||||
n2.setLight(bank, 0, nodemgr);
|
||||
block->setNode(relpos, n2);
|
||||
|
||||
unlighted_nodes.insert(n2pos, current_light);
|
||||
@ -416,6 +420,8 @@ void Map::spreadLight(enum LightBank bank,
|
||||
core::map<v3s16, bool> & from_nodes,
|
||||
core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
const v3s16 dirs[6] = {
|
||||
v3s16(0,0,1), // back
|
||||
v3s16(0,1,0), // top
|
||||
@ -474,7 +480,7 @@ void Map::spreadLight(enum LightBank bank,
|
||||
// Get node straight from the block
|
||||
MapNode n = block->getNode(relpos);
|
||||
|
||||
u8 oldlight = n.getLight(bank);
|
||||
u8 oldlight = n.getLight(bank, nodemgr);
|
||||
u8 newlight = diminish_light(oldlight);
|
||||
|
||||
// Loop through 6 neighbors
|
||||
@ -512,7 +518,7 @@ void Map::spreadLight(enum LightBank bank,
|
||||
If the neighbor is brighter than the current node,
|
||||
add to list (it will light up this node on its turn)
|
||||
*/
|
||||
if(n2.getLight(bank) > undiminish_light(oldlight))
|
||||
if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
|
||||
{
|
||||
lighted_nodes.insert(n2pos, true);
|
||||
//lighted_nodes.push_back(n2pos);
|
||||
@ -522,11 +528,11 @@ void Map::spreadLight(enum LightBank bank,
|
||||
If the neighbor is dimmer than how much light this node
|
||||
would spread on it, add to list
|
||||
*/
|
||||
if(n2.getLight(bank) < newlight)
|
||||
if(n2.getLight(bank, nodemgr) < newlight)
|
||||
{
|
||||
if(n2.light_propagates())
|
||||
if(nodemgr->get(n2).light_propagates)
|
||||
{
|
||||
n2.setLight(bank, newlight);
|
||||
n2.setLight(bank, newlight, nodemgr);
|
||||
block->setNode(relpos, n2);
|
||||
lighted_nodes.insert(n2pos, true);
|
||||
//lighted_nodes.push_back(n2pos);
|
||||
@ -575,6 +581,8 @@ void Map::lightNeighbors(enum LightBank bank,
|
||||
|
||||
v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
v3s16 dirs[6] = {
|
||||
v3s16(0,0,1), // back
|
||||
v3s16(0,1,0), // top
|
||||
@ -600,8 +608,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(n2.getLight(bank) > brightest_light || found_something == false){
|
||||
brightest_light = n2.getLight(bank);
|
||||
if(n2.getLight(bank, nodemgr) > brightest_light || found_something == false){
|
||||
brightest_light = n2.getLight(bank, nodemgr);
|
||||
brightest_pos = n2pos;
|
||||
found_something = true;
|
||||
}
|
||||
@ -624,6 +632,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
|
||||
s16 Map::propagateSunlight(v3s16 start,
|
||||
core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
s16 y = start.Y;
|
||||
for(; ; y--)
|
||||
{
|
||||
@ -642,9 +652,9 @@ s16 Map::propagateSunlight(v3s16 start,
|
||||
v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE;
|
||||
MapNode n = block->getNode(relpos);
|
||||
|
||||
if(n.sunlight_propagates())
|
||||
if(nodemgr->get(n).sunlight_propagates)
|
||||
{
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
|
||||
block->setNode(relpos, n);
|
||||
|
||||
modified_blocks.insert(blockpos, block);
|
||||
@ -670,6 +680,8 @@ void Map::updateLighting(enum LightBank bank,
|
||||
core::map<v3s16, MapBlock*> & a_blocks,
|
||||
core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
/*m_dout<<DTIME<<"Map::updateLighting(): "
|
||||
<<a_blocks.size()<<" blocks."<<std::endl;*/
|
||||
|
||||
@ -713,8 +725,8 @@ void Map::updateLighting(enum LightBank bank,
|
||||
try{
|
||||
v3s16 p(x,y,z);
|
||||
MapNode n = block->getNode(v3s16(x,y,z));
|
||||
u8 oldlight = n.getLight(bank);
|
||||
n.setLight(bank, 0);
|
||||
u8 oldlight = n.getLight(bank, nodemgr);
|
||||
n.setLight(bank, 0, nodemgr);
|
||||
block->setNode(v3s16(x,y,z), n);
|
||||
|
||||
// Collect borders for unlighting
|
||||
@ -865,11 +877,11 @@ void Map::updateLighting(enum LightBank bank,
|
||||
|
||||
{
|
||||
//TimeTaker timer("unSpreadLight");
|
||||
vmanip.unspreadLight(bank, unlight_from, light_sources);
|
||||
vmanip.unspreadLight(bank, unlight_from, light_sources, nodemgr);
|
||||
}
|
||||
{
|
||||
//TimeTaker timer("spreadLight");
|
||||
vmanip.spreadLight(bank, light_sources);
|
||||
vmanip.spreadLight(bank, light_sources, nodemgr);
|
||||
}
|
||||
{
|
||||
//TimeTaker timer("blitBack");
|
||||
@ -905,6 +917,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
/*PrintInfo(m_dout);
|
||||
m_dout<<DTIME<<"Map::addNodeAndUpdate(): p=("
|
||||
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
||||
@ -931,7 +945,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
try{
|
||||
MapNode topnode = getNode(toppos);
|
||||
|
||||
if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
|
||||
if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
|
||||
node_under_sunlight = false;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
@ -942,7 +956,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
/*
|
||||
If the new node is solid and there is grass below, change it to mud
|
||||
*/
|
||||
if(content_features(n).walkable == true)
|
||||
if(nodemgr->get(n).walkable == true)
|
||||
{
|
||||
try{
|
||||
MapNode bottomnode = getNode(bottompos);
|
||||
@ -984,7 +998,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
{
|
||||
enum LightBank bank = banks[i];
|
||||
|
||||
u8 lightwas = getNode(p).getLight(bank);
|
||||
u8 lightwas = getNode(p).getLight(bank, nodemgr);
|
||||
|
||||
// Add the block of the added node to modified_blocks
|
||||
v3s16 blockpos = getNodeBlockPos(p);
|
||||
@ -1001,16 +1015,16 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
// light again into this.
|
||||
unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks);
|
||||
|
||||
n.setLight(bank, 0);
|
||||
n.setLight(bank, 0, nodemgr);
|
||||
}
|
||||
|
||||
/*
|
||||
If node lets sunlight through and is under sunlight, it has
|
||||
sunlight too.
|
||||
*/
|
||||
if(node_under_sunlight && content_features(n).sunlight_propagates)
|
||||
if(node_under_sunlight && nodemgr->get(n).sunlight_propagates)
|
||||
{
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
|
||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1023,7 +1037,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
Add intial metadata
|
||||
*/
|
||||
|
||||
NodeMetadata *meta_proto = content_features(n).initial_metadata;
|
||||
NodeMetadata *meta_proto = nodemgr->get(n).initial_metadata;
|
||||
if(meta_proto)
|
||||
{
|
||||
NodeMetadata *meta = meta_proto->clone(m_gamedef);
|
||||
@ -1038,7 +1052,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
TODO: This could be optimized by mass-unlighting instead
|
||||
of looping
|
||||
*/
|
||||
if(node_under_sunlight && !content_features(n).sunlight_propagates)
|
||||
if(node_under_sunlight && !nodemgr->get(n).sunlight_propagates)
|
||||
{
|
||||
s16 y = p.Y - 1;
|
||||
for(;; y--){
|
||||
@ -1054,12 +1068,12 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
break;
|
||||
}
|
||||
|
||||
if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
|
||||
if(n2.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
|
||||
{
|
||||
unLightNeighbors(LIGHTBANK_DAY,
|
||||
n2pos, n2.getLight(LIGHTBANK_DAY),
|
||||
n2pos, n2.getLight(LIGHTBANK_DAY, nodemgr),
|
||||
light_sources, modified_blocks);
|
||||
n2.setLight(LIGHTBANK_DAY, 0);
|
||||
n2.setLight(LIGHTBANK_DAY, 0, nodemgr);
|
||||
setNode(n2pos, n2);
|
||||
}
|
||||
else
|
||||
@ -1109,7 +1123,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
v3s16 p2 = p + dirs[i];
|
||||
|
||||
MapNode n2 = getNode(p2);
|
||||
if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
|
||||
if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
|
||||
{
|
||||
m_transforming_liquid.push_back(p2);
|
||||
}
|
||||
@ -1125,6 +1139,8 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
void Map::removeNodeAndUpdate(v3s16 p,
|
||||
core::map<v3s16, MapBlock*> &modified_blocks)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
/*PrintInfo(m_dout);
|
||||
m_dout<<DTIME<<"Map::removeNodeAndUpdate(): p=("
|
||||
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
||||
@ -1143,7 +1159,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
try{
|
||||
MapNode topnode = getNode(toppos);
|
||||
|
||||
if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
|
||||
if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
|
||||
node_under_sunlight = false;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
@ -1165,7 +1181,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
Unlight neighbors (in case the node is a light source)
|
||||
*/
|
||||
unLightNeighbors(bank, p,
|
||||
getNode(p).getLight(bank),
|
||||
getNode(p).getLight(bank, nodemgr),
|
||||
light_sources, modified_blocks);
|
||||
}
|
||||
|
||||
@ -1227,7 +1243,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
// TODO: Is this needed? Lighting is cleared up there already.
|
||||
try{
|
||||
MapNode n = getNode(p);
|
||||
n.setLight(LIGHTBANK_DAY, 0);
|
||||
n.setLight(LIGHTBANK_DAY, 0, nodemgr);
|
||||
setNode(p, n);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
@ -1283,7 +1299,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
v3s16 p2 = p + dirs[i];
|
||||
|
||||
MapNode n2 = getNode(p2);
|
||||
if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
|
||||
if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
|
||||
{
|
||||
m_transforming_liquid.push_back(p2);
|
||||
}
|
||||
@ -1580,6 +1596,8 @@ struct NodeNeighbor {
|
||||
|
||||
void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
//TimeTaker timer("transformLiquids()");
|
||||
|
||||
@ -1614,11 +1632,11 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
*/
|
||||
s8 liquid_level = -1;
|
||||
u8 liquid_kind = CONTENT_IGNORE;
|
||||
LiquidType liquid_type = content_features(n0.getContent()).liquid_type;
|
||||
LiquidType liquid_type = nodemgr->get(n0).liquid_type;
|
||||
switch (liquid_type) {
|
||||
case LIQUID_SOURCE:
|
||||
liquid_level = LIQUID_LEVEL_SOURCE;
|
||||
liquid_kind = content_features(n0.getContent()).liquid_alternative_flowing;
|
||||
liquid_kind = nodemgr->get(n0).liquid_alternative_flowing;
|
||||
break;
|
||||
case LIQUID_FLOWING:
|
||||
liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
|
||||
@ -1658,7 +1676,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
}
|
||||
v3s16 npos = p0 + dirs[i];
|
||||
NodeNeighbor nb = {getNodeNoEx(npos), nt, npos};
|
||||
switch (content_features(nb.n.getContent()).liquid_type) {
|
||||
switch (nodemgr->get(nb.n.getContent()).liquid_type) {
|
||||
case LIQUID_NONE:
|
||||
if (nb.n.getContent() == CONTENT_AIR) {
|
||||
airs[num_airs++] = nb;
|
||||
@ -1678,8 +1696,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
case LIQUID_SOURCE:
|
||||
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
|
||||
if (liquid_kind == CONTENT_AIR)
|
||||
liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
|
||||
if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
|
||||
liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
|
||||
if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
|
||||
neutrals[num_neutrals++] = nb;
|
||||
} else {
|
||||
sources[num_sources++] = nb;
|
||||
@ -1688,8 +1706,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
case LIQUID_FLOWING:
|
||||
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
|
||||
if (liquid_kind == CONTENT_AIR)
|
||||
liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
|
||||
if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
|
||||
liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
|
||||
if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
|
||||
neutrals[num_neutrals++] = nb;
|
||||
} else {
|
||||
flows[num_flows++] = nb;
|
||||
@ -1710,7 +1728,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
|
||||
// or the flowing alternative of the first of the surrounding sources (if it's air), so
|
||||
// it's perfectly safe to use liquid_kind here to determine the new node content.
|
||||
new_node_content = content_features(liquid_kind).liquid_alternative_source;
|
||||
new_node_content = nodemgr->get(liquid_kind).liquid_alternative_source;
|
||||
} else if (num_sources == 1 && sources[0].t != NEIGHBOR_LOWER) {
|
||||
// liquid_kind is set properly, see above
|
||||
new_node_content = liquid_kind;
|
||||
@ -1739,7 +1757,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
}
|
||||
}
|
||||
|
||||
u8 viscosity = content_features(liquid_kind).liquid_viscosity;
|
||||
u8 viscosity = nodemgr->get(liquid_kind).liquid_viscosity;
|
||||
if (viscosity > 1 && max_node_level != liquid_level) {
|
||||
// amount to gain, limited by viscosity
|
||||
// must be at least 1 in absolute value
|
||||
@ -1765,7 +1783,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
/*
|
||||
check if anything has changed. if not, just continue with the next node.
|
||||
*/
|
||||
if (new_node_content == n0.getContent() && (content_features(n0.getContent()).liquid_type != LIQUID_FLOWING ||
|
||||
if (new_node_content == n0.getContent() && (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
|
||||
((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
|
||||
((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
|
||||
== flowing_down)))
|
||||
@ -1776,7 +1794,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
update the current node
|
||||
*/
|
||||
//bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
|
||||
if (content_features(new_node_content).liquid_type == LIQUID_FLOWING) {
|
||||
if (nodemgr->get(new_node_content).liquid_type == LIQUID_FLOWING) {
|
||||
// set level to last 3 bits, flowing down bit to 4th bit
|
||||
n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
|
||||
} else {
|
||||
@ -1790,14 +1808,14 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||
if(block != NULL) {
|
||||
modified_blocks.insert(blockpos, block);
|
||||
// If node emits light, MapBlock requires lighting update
|
||||
if(content_features(n0).light_source != 0)
|
||||
if(nodemgr->get(n0).light_source != 0)
|
||||
lighting_modified_blocks[block->getPos()] = block;
|
||||
}
|
||||
|
||||
/*
|
||||
enqueue neighbors for update if neccessary
|
||||
*/
|
||||
switch (content_features(n0.getContent()).liquid_type) {
|
||||
switch (nodemgr->get(n0.getContent()).liquid_type) {
|
||||
case LIQUID_SOURCE:
|
||||
case LIQUID_FLOWING:
|
||||
// make sure source flows into all neighboring nodes
|
||||
@ -2082,6 +2100,7 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
|
||||
data->no_op = false;
|
||||
data->seed = m_seed;
|
||||
data->blockpos = blockpos;
|
||||
data->nodemgr = m_gamedef->ndef();
|
||||
|
||||
/*
|
||||
Create the whole area of this and the neighboring blocks
|
||||
@ -2389,7 +2408,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
|
||||
Generate blank sector
|
||||
*/
|
||||
|
||||
sector = new ServerMapSector(this, p2d);
|
||||
sector = new ServerMapSector(this, p2d, m_gamedef);
|
||||
|
||||
// Sector position on map in nodes
|
||||
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
|
||||
@ -3054,7 +3073,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
|
||||
<<fullpath<<" doesn't exist but directory does."
|
||||
<<" Continuing with a sector with no metadata."
|
||||
<<std::endl;*/
|
||||
sector = new ServerMapSector(this, p2d);
|
||||
sector = new ServerMapSector(this, p2d, m_gamedef);
|
||||
m_sectors.insert(p2d, sector);
|
||||
}
|
||||
else
|
||||
@ -3065,7 +3084,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
|
||||
else
|
||||
{
|
||||
sector = ServerMapSector::deSerialize
|
||||
(is, this, p2d, m_sectors);
|
||||
(is, this, p2d, m_sectors, m_gamedef);
|
||||
if(save_after_load)
|
||||
saveSectorMeta(sector);
|
||||
}
|
||||
@ -3310,7 +3329,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
|
||||
}
|
||||
|
||||
// Read basic data
|
||||
block->deSerialize(is, version, m_gamedef);
|
||||
block->deSerialize(is, version);
|
||||
|
||||
// Read extra data stored on disk
|
||||
block->deSerializeDiskExtra(is, version);
|
||||
@ -3380,7 +3399,7 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
|
||||
}
|
||||
|
||||
// Read basic data
|
||||
block->deSerialize(is, version, m_gamedef);
|
||||
block->deSerialize(is, version);
|
||||
|
||||
// Read extra data stored on disk
|
||||
block->deSerializeDiskExtra(is, version);
|
||||
@ -3567,7 +3586,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
|
||||
}
|
||||
|
||||
// Create a sector
|
||||
ClientMapSector *sector = new ClientMapSector(this, p2d);
|
||||
ClientMapSector *sector = new ClientMapSector(this, p2d, m_gamedef);
|
||||
|
||||
{
|
||||
//JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
|
||||
@ -3617,7 +3636,7 @@ void ClientMap::OnRegisterSceneNode()
|
||||
}
|
||||
|
||||
static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
|
||||
float start_off, float end_off, u32 needed_count)
|
||||
float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr)
|
||||
{
|
||||
float d0 = (float)BS * p0.getDistanceFrom(p1);
|
||||
v3s16 u0 = p1 - p0;
|
||||
@ -3630,7 +3649,7 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
|
||||
v3s16 p = floatToInt(pf, BS);
|
||||
MapNode n = map->getNodeNoEx(p);
|
||||
bool is_transparent = false;
|
||||
ContentFeatures &f = content_features(n);
|
||||
const ContentFeatures &f = nodemgr->get(n);
|
||||
if(f.solidness == 0)
|
||||
is_transparent = (f.visual_solidness != 2);
|
||||
else
|
||||
@ -3647,6 +3666,8 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
|
||||
|
||||
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
//m_dout<<DTIME<<"Rendering map..."<<std::endl;
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
@ -3855,23 +3876,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
u32 needed_count = 1;
|
||||
if(
|
||||
isOccluded(this, spn, cpn + v3s16(0,0,0),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(bs2,bs2,-bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(bs2,-bs2,bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(bs2,-bs2,-bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(-bs2,bs2,bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(-bs2,bs2,-bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,bs2),
|
||||
step, stepfac, startoff, endoff, needed_count) &&
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr) &&
|
||||
isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
|
||||
step, stepfac, startoff, endoff, needed_count)
|
||||
step, stepfac, startoff, endoff, needed_count, nodemgr)
|
||||
)
|
||||
{
|
||||
blocks_occlusion_culled++;
|
||||
@ -4016,6 +4037,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
|
||||
void ClientMap::renderPostFx()
|
||||
{
|
||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||
|
||||
// Sadly ISceneManager has no "post effects" render pass, in that case we
|
||||
// could just register for that and handle it in renderMap().
|
||||
|
||||
@ -4027,7 +4050,7 @@ void ClientMap::renderPostFx()
|
||||
|
||||
// - If the player is in a solid node, make everything black.
|
||||
// - If the player is in liquid, draw a semi-transparent overlay.
|
||||
ContentFeatures& features = content_features(n);
|
||||
const ContentFeatures& features = nodemgr->get(n);
|
||||
video::SColor post_effect_color = features.post_effect_color;
|
||||
if(features.solidness == 2 && g_settings->getBool("free_move") == false)
|
||||
{
|
||||
@ -4170,15 +4193,14 @@ void ClientMap::expireMeshes(bool only_daynight_diffed)
|
||||
}
|
||||
}
|
||||
|
||||
void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
|
||||
ITextureSource *tsrc)
|
||||
void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
|
||||
{
|
||||
assert(mapType() == MAPTYPE_CLIENT);
|
||||
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daynight_ratio, tsrc);
|
||||
b->updateMesh(daynight_ratio);
|
||||
//b->setMeshExpired(true);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
@ -4186,21 +4208,21 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(-1,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daynight_ratio, tsrc);
|
||||
b->updateMesh(daynight_ratio);
|
||||
//b->setMeshExpired(true);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,-1,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daynight_ratio, tsrc);
|
||||
b->updateMesh(daynight_ratio);
|
||||
//b->setMeshExpired(true);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,-1);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daynight_ratio, tsrc);
|
||||
b->updateMesh(daynight_ratio);
|
||||
//b->setMeshExpired(true);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
|
@ -590,8 +590,7 @@ public:
|
||||
Update the faces of the given block and blocks on the
|
||||
leading edge, without threading. Rarely used.
|
||||
*/
|
||||
void updateMeshes(v3s16 blockpos, u32 daynight_ratio,
|
||||
ITextureSource *tsrc);
|
||||
void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
|
||||
|
||||
// Update meshes that touch the node
|
||||
//void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
175
src/nodedef.cpp
Normal 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);
|
||||
}
|
||||
|
@ -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
|
@ -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)
|
||||
|
32
src/player.h
32
src/player.h
@ -30,13 +30,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
|
||||
class Map;
|
||||
class IGameDef;
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
Player();
|
||||
Player(IGameDef *gamedef);
|
||||
virtual ~Player();
|
||||
|
||||
void resetInventory();
|
||||
@ -141,7 +141,7 @@ public:
|
||||
deSerialize stops reading exactly at the right point.
|
||||
*/
|
||||
void serialize(std::ostream &os);
|
||||
void deSerialize(std::istream &is, IGameDef *gamedef);
|
||||
void deSerialize(std::istream &is);
|
||||
|
||||
bool touching_ground;
|
||||
// This oscillates so that the player jumps a bit above the surface
|
||||
@ -164,6 +164,8 @@ public:
|
||||
u16 peer_id;
|
||||
|
||||
protected:
|
||||
IGameDef *m_gamedef;
|
||||
|
||||
char m_name[PLAYERNAME_SIZE];
|
||||
u16 m_selected_item;
|
||||
f32 m_pitch;
|
||||
@ -185,26 +187,15 @@ public:
|
||||
class ServerRemotePlayer : public Player, public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
ServerRemotePlayer(ServerEnvironment *env):
|
||||
ServerActiveObject(env, v3f(0,0,0))
|
||||
{
|
||||
}
|
||||
ServerRemotePlayer(ServerEnvironment *env);
|
||||
ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
|
||||
const char *name_):
|
||||
ServerActiveObject(env, pos_)
|
||||
{
|
||||
setPosition(pos_);
|
||||
peer_id = peer_id_;
|
||||
updateName(name_);
|
||||
}
|
||||
const char *name_);
|
||||
|
||||
virtual ~ServerRemotePlayer()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
virtual bool isLocal() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
{ return false; }
|
||||
|
||||
virtual void move(f32 dtime, Map &map, f32 pos_max_d)
|
||||
{
|
||||
@ -242,6 +233,7 @@ class RemotePlayer : public Player, public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
RemotePlayer(
|
||||
IGameDef *gamedef,
|
||||
scene::ISceneNode* parent=NULL,
|
||||
IrrlichtDevice *device=NULL,
|
||||
s32 id=0);
|
||||
@ -378,7 +370,7 @@ struct PlayerControl
|
||||
class LocalPlayer : public Player
|
||||
{
|
||||
public:
|
||||
LocalPlayer();
|
||||
LocalPlayer(IGameDef *gamedef);
|
||||
virtual ~LocalPlayer();
|
||||
|
||||
bool isLocal() const
|
||||
|
@ -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;
|
||||
|
15
src/server.h
15
src/server.h
@ -32,7 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "gamedef.h"
|
||||
struct LuaState;
|
||||
typedef struct lua_State lua_State;
|
||||
class IToolDefManager;
|
||||
class IWritableToolDefManager;
|
||||
class IWritableNodeDefManager;
|
||||
|
||||
/*
|
||||
Some random functions
|
||||
@ -486,10 +487,9 @@ public:
|
||||
|
||||
// IGameDef interface
|
||||
// Under envlock
|
||||
virtual IToolDefManager* getToolDefManager()
|
||||
{ return m_toolmgr; }
|
||||
virtual INodeDefManager* getNodeDefManager()
|
||||
{ assert(0); return NULL; } // TODO
|
||||
virtual IToolDefManager* getToolDefManager();
|
||||
virtual INodeDefManager* getNodeDefManager();
|
||||
virtual ITextureSource* getTextureSource();
|
||||
|
||||
private:
|
||||
|
||||
@ -616,7 +616,10 @@ private:
|
||||
lua_State *m_lua;
|
||||
|
||||
// Tool definition manager
|
||||
IToolDefManager *m_toolmgr;
|
||||
IWritableToolDefManager *m_toolmgr;
|
||||
|
||||
// Node definition manager
|
||||
IWritableNodeDefManager *m_nodemgr;
|
||||
|
||||
/*
|
||||
Threads
|
||||
|
@ -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();
|
||||
|
||||
/*
|
||||
|
106
src/test.cpp
106
src/test.cpp
@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <sstream>
|
||||
#include "porting.h"
|
||||
#include "content_mapnode.h"
|
||||
#include "nodedef.h"
|
||||
#include "mapsector.h"
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
@ -216,26 +217,26 @@ struct TestCompress
|
||||
|
||||
struct TestMapNode
|
||||
{
|
||||
void Run()
|
||||
void Run(INodeDefManager *nodedef)
|
||||
{
|
||||
MapNode n;
|
||||
|
||||
// Default values
|
||||
assert(n.getContent() == CONTENT_AIR);
|
||||
assert(n.getLight(LIGHTBANK_DAY) == 0);
|
||||
assert(n.getLight(LIGHTBANK_NIGHT) == 0);
|
||||
assert(n.getLight(LIGHTBANK_DAY, nodedef) == 0);
|
||||
assert(n.getLight(LIGHTBANK_NIGHT, nodedef) == 0);
|
||||
|
||||
// Transparency
|
||||
n.setContent(CONTENT_AIR);
|
||||
assert(n.light_propagates() == true);
|
||||
assert(nodedef->get(n).light_propagates == true);
|
||||
n.setContent(CONTENT_STONE);
|
||||
assert(n.light_propagates() == false);
|
||||
assert(nodedef->get(n).light_propagates == false);
|
||||
}
|
||||
};
|
||||
|
||||
struct TestVoxelManipulator
|
||||
{
|
||||
void Run()
|
||||
void Run(INodeDefManager *nodedef)
|
||||
{
|
||||
/*
|
||||
VoxelArea
|
||||
@ -278,13 +279,13 @@ struct TestVoxelManipulator
|
||||
|
||||
VoxelManipulator v;
|
||||
|
||||
v.print(infostream);
|
||||
v.print(infostream, nodedef);
|
||||
|
||||
infostream<<"*** Setting (-1,0,-1)=2 ***"<<std::endl;
|
||||
|
||||
v.setNodeNoRef(v3s16(-1,0,-1), MapNode(2));
|
||||
|
||||
v.print(infostream);
|
||||
v.print(infostream, nodedef);
|
||||
|
||||
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
|
||||
|
||||
@ -292,85 +293,16 @@ struct TestVoxelManipulator
|
||||
|
||||
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1)));
|
||||
|
||||
v.print(infostream);
|
||||
v.print(infostream, nodedef);
|
||||
|
||||
infostream<<"*** Adding area ***"<<std::endl;
|
||||
|
||||
v.addArea(a);
|
||||
|
||||
v.print(infostream);
|
||||
v.print(infostream, nodedef);
|
||||
|
||||
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
|
||||
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
|
||||
|
||||
#if 0
|
||||
/*
|
||||
Water stuff
|
||||
*/
|
||||
|
||||
v.clear();
|
||||
|
||||
const char *content =
|
||||
"#...###### "
|
||||
"#...##..## "
|
||||
"#........ .."
|
||||
"############"
|
||||
|
||||
"#...###### "
|
||||
"#...##..## "
|
||||
"#........# "
|
||||
"############"
|
||||
;
|
||||
|
||||
v3s16 size(12, 4, 2);
|
||||
VoxelArea area(v3s16(0,0,0), size-v3s16(1,1,1));
|
||||
|
||||
const char *p = content;
|
||||
for(s16 z=0; z<size.Z; z++)
|
||||
for(s16 y=size.Y-1; y>=0; y--)
|
||||
for(s16 x=0; x<size.X; x++)
|
||||
{
|
||||
MapNode n;
|
||||
//n.pressure = size.Y - y;
|
||||
if(*p == '#')
|
||||
n.setContent(CONTENT_STONE);
|
||||
else if(*p == '.')
|
||||
n.setContent(CONTENT_WATER);
|
||||
else if(*p == ' ')
|
||||
n.setContent(CONTENT_AIR);
|
||||
else
|
||||
assert(0);
|
||||
v.setNode(v3s16(x,y,z), n);
|
||||
p++;
|
||||
}
|
||||
|
||||
v.print(infostream, VOXELPRINT_WATERPRESSURE);
|
||||
|
||||
core::map<v3s16, u8> active_nodes;
|
||||
v.updateAreaWaterPressure(area, active_nodes);
|
||||
|
||||
v.print(infostream, VOXELPRINT_WATERPRESSURE);
|
||||
|
||||
//s16 highest_y = -32768;
|
||||
/*
|
||||
NOTE: These are commented out because this behaviour is changed
|
||||
all the time
|
||||
*/
|
||||
//assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
|
||||
//assert(highest_y == 3);
|
||||
/*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
|
||||
//assert(highest_y == 3);*/
|
||||
|
||||
active_nodes.clear();
|
||||
active_nodes[v3s16(9,1,0)] = 1;
|
||||
//v.flowWater(active_nodes, 0, true, 1000);
|
||||
v.flowWater(active_nodes, 0, false, 1000);
|
||||
|
||||
infostream<<"Final result of flowWater:"<<std::endl;
|
||||
v.print(infostream, VOXELPRINT_WATERPRESSURE);
|
||||
#endif
|
||||
|
||||
//assert(0);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1143,15 +1075,27 @@ struct TestConnection
|
||||
x.Run();\
|
||||
}
|
||||
|
||||
#define TESTPARAMS(X, ...)\
|
||||
{\
|
||||
X x;\
|
||||
infostream<<"Running " #X <<std::endl;\
|
||||
x.Run(__VA_ARGS__);\
|
||||
}
|
||||
|
||||
void run_tests()
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
// Create node definitions
|
||||
IWritableNodeDefManager *nodedef = createNodeDefManager(NULL);
|
||||
content_mapnode_init(NULL, nodedef);
|
||||
|
||||
infostream<<"run_tests() started"<<std::endl;
|
||||
TEST(TestUtilities);
|
||||
TEST(TestSettings);
|
||||
TEST(TestCompress);
|
||||
TEST(TestMapNode);
|
||||
TEST(TestVoxelManipulator);
|
||||
TESTPARAMS(TestMapNode, nodedef);
|
||||
TESTPARAMS(TestVoxelManipulator, nodedef);
|
||||
//TEST(TestMapBlock);
|
||||
//TEST(TestMapSector);
|
||||
if(INTERNET_SIMULATOR == false){
|
||||
|
187
src/tile.cpp
187
src/tile.cpp
@ -27,7 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "log.h"
|
||||
#include "mapnode.h" // For texture atlas making
|
||||
#include "mineral.h" // For texture atlas making
|
||||
#include "mapnode_contentfeatures.h" // For texture atlas making
|
||||
#include "nodedef.h" // For texture atlas making
|
||||
#include "gamedef.h"
|
||||
|
||||
/*
|
||||
A cache from texture name to texture path
|
||||
@ -148,6 +149,142 @@ std::string getTexturePath(const std::string &filename)
|
||||
TextureSource
|
||||
*/
|
||||
|
||||
class TextureSource : public IWritableTextureSource
|
||||
{
|
||||
public:
|
||||
TextureSource(IrrlichtDevice *device);
|
||||
~TextureSource();
|
||||
|
||||
/*
|
||||
Example case:
|
||||
Now, assume a texture with the id 1 exists, and has the name
|
||||
"stone.png^mineral1".
|
||||
Then a random thread calls getTextureId for a texture called
|
||||
"stone.png^mineral1^crack0".
|
||||
...Now, WTF should happen? Well:
|
||||
- getTextureId strips off stuff recursively from the end until
|
||||
the remaining part is found, or nothing is left when
|
||||
something is stripped out
|
||||
|
||||
But it is slow to search for textures by names and modify them
|
||||
like that?
|
||||
- ContentFeatures is made to contain ids for the basic plain
|
||||
textures
|
||||
- Crack textures can be slow by themselves, but the framework
|
||||
must be fast.
|
||||
|
||||
Example case #2:
|
||||
- Assume a texture with the id 1 exists, and has the name
|
||||
"stone.png^mineral1" and is specified as a part of some atlas.
|
||||
- Now MapBlock::getNodeTile() stumbles upon a node which uses
|
||||
texture id 1, and finds out that NODEMOD_CRACK must be applied
|
||||
with progression=0
|
||||
- It finds out the name of the texture with getTextureName(1),
|
||||
appends "^crack0" to it and gets a new texture id with
|
||||
getTextureId("stone.png^mineral1^crack0")
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Gets a texture id from cache or
|
||||
- if main thread, from getTextureIdDirect
|
||||
- if other thread, adds to request queue and waits for main thread
|
||||
*/
|
||||
u32 getTextureId(const std::string &name);
|
||||
|
||||
/*
|
||||
Example names:
|
||||
"stone.png"
|
||||
"stone.png^crack2"
|
||||
"stone.png^blit:mineral_coal.png"
|
||||
"stone.png^blit:mineral_coal.png^crack1"
|
||||
|
||||
- If texture specified by name is found from cache, return the
|
||||
cached id.
|
||||
- Otherwise generate the texture, add to cache and return id.
|
||||
Recursion is used to find out the largest found part of the
|
||||
texture and continue based on it.
|
||||
|
||||
The id 0 points to a NULL texture. It is returned in case of error.
|
||||
*/
|
||||
u32 getTextureIdDirect(const std::string &name);
|
||||
|
||||
/*
|
||||
Finds out the name of a cached texture.
|
||||
*/
|
||||
std::string getTextureName(u32 id);
|
||||
|
||||
/*
|
||||
If texture specified by the name pointed by the id doesn't
|
||||
exist, create it, then return the cached texture.
|
||||
|
||||
Can be called from any thread. If called from some other thread
|
||||
and not found in cache, the call is queued to the main thread
|
||||
for processing.
|
||||
*/
|
||||
AtlasPointer getTexture(u32 id);
|
||||
|
||||
AtlasPointer getTexture(const std::string &name)
|
||||
{
|
||||
return getTexture(getTextureId(name));
|
||||
}
|
||||
|
||||
// Gets a separate texture
|
||||
video::ITexture* getTextureRaw(const std::string &name)
|
||||
{
|
||||
AtlasPointer ap = getTexture(name);
|
||||
return ap.atlas;
|
||||
}
|
||||
|
||||
/*
|
||||
Update new texture pointer and texture coordinates to an
|
||||
AtlasPointer based on it's texture id
|
||||
*/
|
||||
void updateAP(AtlasPointer &ap);
|
||||
|
||||
/*
|
||||
Build the main texture atlas which contains most of the
|
||||
textures.
|
||||
|
||||
This is called by the constructor.
|
||||
*/
|
||||
void buildMainAtlas(class IGameDef *gamedef);
|
||||
|
||||
/*
|
||||
Processes queued texture requests from other threads.
|
||||
|
||||
Shall be called from the main thread.
|
||||
*/
|
||||
void processQueue();
|
||||
|
||||
private:
|
||||
|
||||
// The id of the thread that is allowed to use irrlicht directly
|
||||
threadid_t m_main_thread;
|
||||
// The irrlicht device
|
||||
IrrlichtDevice *m_device;
|
||||
|
||||
// A texture id is index in this array.
|
||||
// The first position contains a NULL texture.
|
||||
core::array<SourceAtlasPointer> m_atlaspointer_cache;
|
||||
// Maps a texture name to an index in the former.
|
||||
core::map<std::string, u32> m_name_to_id;
|
||||
// The two former containers are behind this mutex
|
||||
JMutex m_atlaspointer_cache_mutex;
|
||||
|
||||
// Main texture atlas. This is filled at startup and is then not touched.
|
||||
video::IImage *m_main_atlas_image;
|
||||
video::ITexture *m_main_atlas_texture;
|
||||
|
||||
// Queued texture fetches (to be processed by the main thread)
|
||||
RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
|
||||
};
|
||||
|
||||
IWritableTextureSource* createTextureSource(IrrlichtDevice *device)
|
||||
{
|
||||
return new TextureSource(device);
|
||||
}
|
||||
|
||||
TextureSource::TextureSource(IrrlichtDevice *device):
|
||||
m_device(device),
|
||||
m_main_atlas_image(NULL),
|
||||
@ -162,12 +299,6 @@ TextureSource::TextureSource(IrrlichtDevice *device):
|
||||
// Add a NULL AtlasPointer as the first index, named ""
|
||||
m_atlaspointer_cache.push_back(SourceAtlasPointer(""));
|
||||
m_name_to_id[""] = 0;
|
||||
|
||||
// Build main texture atlas
|
||||
if(g_settings->getBool("enable_texture_atlas"))
|
||||
buildMainAtlas();
|
||||
else
|
||||
infostream<<"Not building texture atlas."<<std::endl;
|
||||
}
|
||||
|
||||
TextureSource::~TextureSource()
|
||||
@ -487,8 +618,17 @@ AtlasPointer TextureSource::getTexture(u32 id)
|
||||
return m_atlaspointer_cache[id].a;
|
||||
}
|
||||
|
||||
void TextureSource::buildMainAtlas()
|
||||
void TextureSource::updateAP(AtlasPointer &ap)
|
||||
{
|
||||
AtlasPointer ap2 = getTexture(ap.id);
|
||||
ap = ap2;
|
||||
}
|
||||
|
||||
void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
||||
{
|
||||
assert(gamedef->tsrc() == this);
|
||||
INodeDefManager *ndef = gamedef->ndef();
|
||||
|
||||
infostream<<"TextureSource::buildMainAtlas()"<<std::endl;
|
||||
|
||||
//return; // Disable (for testing)
|
||||
@ -521,15 +661,15 @@ void TextureSource::buildMainAtlas()
|
||||
{
|
||||
if(j == CONTENT_IGNORE || j == CONTENT_AIR)
|
||||
continue;
|
||||
ContentFeatures *f = &content_features(j);
|
||||
for(core::map<std::string, bool>::Iterator
|
||||
i = f->used_texturenames.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
const ContentFeatures &f = ndef->get(j);
|
||||
for(std::set<std::string>::const_iterator
|
||||
i = f.used_texturenames.begin();
|
||||
i != f.used_texturenames.end(); i++)
|
||||
{
|
||||
std::string name = i.getNode()->getKey();
|
||||
std::string name = *i;
|
||||
sourcelist[name] = true;
|
||||
|
||||
if(f->often_contains_mineral){
|
||||
if(f.often_contains_mineral){
|
||||
for(int k=1; k<MINERAL_COUNT; k++){
|
||||
std::string mineraltexture = mineral_block_texture(k);
|
||||
std::string fulltexture = name + "^" + mineraltexture;
|
||||
@ -658,8 +798,18 @@ void TextureSource::buildMainAtlas()
|
||||
Add texture to caches
|
||||
*/
|
||||
|
||||
// Get next id
|
||||
bool reuse_old_id = false;
|
||||
u32 id = m_atlaspointer_cache.size();
|
||||
// Check old id without fetching a texture
|
||||
core::map<std::string, u32>::Node *n;
|
||||
n = m_name_to_id.find(name);
|
||||
// If it exists, we will replace the old definition
|
||||
if(n){
|
||||
id = n->getValue();
|
||||
reuse_old_id = true;
|
||||
}
|
||||
infostream<<"TextureSource::buildMainAtlas(): "
|
||||
<<"Replacing old AtlasPointer"<<std::endl;
|
||||
|
||||
// Create AtlasPointer
|
||||
AtlasPointer ap(id);
|
||||
@ -672,8 +822,11 @@ void TextureSource::buildMainAtlas()
|
||||
|
||||
// Create SourceAtlasPointer and add to containers
|
||||
SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
|
||||
m_atlaspointer_cache.push_back(nap);
|
||||
m_name_to_id.insert(name, id);
|
||||
if(reuse_old_id)
|
||||
m_atlaspointer_cache[id] = nap;
|
||||
else
|
||||
m_atlaspointer_cache.push_back(nap);
|
||||
m_name_to_id[name] = id;
|
||||
|
||||
// Increment position
|
||||
pos_in_atlas.Y += dim.Height + padding * 2;
|
||||
|
143
src/tile.h
143
src/tile.h
@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "utility.h"
|
||||
#include <string>
|
||||
|
||||
class IGameDef;
|
||||
|
||||
/*
|
||||
tile.{h,cpp}: Texture handling stuff.
|
||||
*/
|
||||
@ -120,8 +122,9 @@ struct SourceAtlasPointer
|
||||
};
|
||||
|
||||
/*
|
||||
Implementation (to be used as a no-op on the server)
|
||||
TextureSource creates and caches textures.
|
||||
*/
|
||||
|
||||
class ITextureSource
|
||||
{
|
||||
public:
|
||||
@ -137,133 +140,27 @@ public:
|
||||
{return NULL;}
|
||||
};
|
||||
|
||||
/*
|
||||
Creates and caches textures.
|
||||
*/
|
||||
class TextureSource : public ITextureSource
|
||||
class IWritableTextureSource : public ITextureSource
|
||||
{
|
||||
public:
|
||||
TextureSource(IrrlichtDevice *device);
|
||||
~TextureSource();
|
||||
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,
|
||||
|
@ -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();
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
13
src/voxel.h
13
src/voxel.h
@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "debug.h"
|
||||
#include "mapnode.h"
|
||||
|
||||
class INodeDefManager;
|
||||
|
||||
// For VC++
|
||||
#undef min
|
||||
#undef max
|
||||
@ -475,7 +477,8 @@ public:
|
||||
|
||||
virtual void clear();
|
||||
|
||||
void print(std::ostream &o, VoxelPrintMode mode=VOXELPRINT_MATERIAL);
|
||||
void print(std::ostream &o, INodeDefManager *nodemgr,
|
||||
VoxelPrintMode mode=VOXELPRINT_MATERIAL);
|
||||
|
||||
void addArea(VoxelArea area);
|
||||
|
||||
@ -497,14 +500,14 @@ public:
|
||||
void clearFlag(u8 flag);
|
||||
|
||||
void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
|
||||
core::map<v3s16, bool> & light_sources);
|
||||
core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
|
||||
void unspreadLight(enum LightBank bank,
|
||||
core::map<v3s16, u8> & from_nodes,
|
||||
core::map<v3s16, bool> & light_sources);
|
||||
core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
|
||||
|
||||
void spreadLight(enum LightBank bank, v3s16 p);
|
||||
void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
|
||||
void spreadLight(enum LightBank bank,
|
||||
core::map<v3s16, bool> & from_nodes);
|
||||
core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr);
|
||||
|
||||
/*
|
||||
Virtual functions
|
||||
|
Loading…
Reference in New Issue
Block a user