)
set(common_SRCS
+ nodemetadata.cpp
serverobject.cpp
noise.cpp
mineral.cpp
while(getRun())
{
- m_client->asyncStep();
+ //m_client->asyncStep();
//m_client->updateSomeExpiredMeshes();
}*/
}
+#if 0
float Client::asyncStep()
{
DSTACK(__FUNCTION_NAME);
return dtime;*/
return 0.0;
}
+#endif
// Virtual methods from con::PeerHandler
void Client::peerAdded(con::Peer *peer)
// Ignore too small packet
if(datasize < 8)
return true;
- /*if(datasize < 8 + MapBlock::serializedLength(ser_version))
- goto getdata;*/
v3s16 p;
p.X = readS16(&data[2]);
block->deSerialize(istr, ser_version);
sector->insertBlock(block);
//block->setChangedFlag();
-
- //DEBUG
- /*NodeMod mod;
- mod.type = NODEMOD_CHANGECONTENT;
- mod.param = CONTENT_MESE;
- block->setTempMod(v3s16(8,10,8), mod);
- block->setTempMod(v3s16(8,9,8), mod);
- block->setTempMod(v3s16(8,8,8), mod);
- block->setTempMod(v3s16(8,7,8), mod);
- block->setTempMod(v3s16(8,6,8), mod);*/
-
- /*
- Add some coulds
- Well, this is a dumb way to do it, they should just
- be drawn as separate objects.
- */
- /*if(p.Y == 3)
- {
- NodeMod mod;
- mod.type = NODEMOD_CHANGECONTENT;
- mod.param = CONTENT_CLOUD;
- v3s16 p2;
- p2.Y = 8;
- for(p2.X=3; p2.X<=13; p2.X++)
- for(p2.Z=3; p2.Z<=13; p2.Z++)
- {
- block->setTempMod(p2, mod);
- }
- }*/
}
} //envlock
return m_env.getMap().getNode(p);
}
+NodeMetadata* Client::getNodeMetadataClone(v3s16 p)
+{
+ JMutexAutoLock envlock(m_env_mutex);
+ return m_env.getMap().getNodeMetadataClone(p);
+}
+
v3f Client::getPlayerPosition()
{
JMutexAutoLock envlock(m_env_mutex);
// Called from updater thread
// Returns dtime
- float asyncStep();
+ //float asyncStep();
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
// Returns true if something was received
// Returns InvalidPositionException if not found
MapNode getNode(v3s16 p);
+ // Wrapper to Map
+ NodeMetadata* getNodeMetadataClone(v3s16 p);
v3f getPlayerPosition();
}\r
}\r
}\r
+ else if(n.d == CONTENT_SIGN_WALL)\r
+ {\r
+ v3s16 dir = unpackDir(n.dir);\r
+ v3f dir_f = v3f(dir.X, dir.Y, dir.Z);\r
+ dir_f *= BS/2 - BS/6 - BS/20;\r
+ v3f cpf = npf + dir_f;\r
+ f32 distance = (cpf - camera_position).getLength();\r
+\r
+ v3f vertices[4] =\r
+ {\r
+ v3f(BS*0.42,-BS*0.35,-BS*0.4),\r
+ v3f(BS*0.49, BS*0.35, BS*0.4),\r
+ };\r
+\r
+ for(s32 i=0; i<2; i++)\r
+ {\r
+ if(dir == v3s16(1,0,0))\r
+ vertices[i].rotateXZBy(0);\r
+ if(dir == v3s16(-1,0,0))\r
+ vertices[i].rotateXZBy(180);\r
+ if(dir == v3s16(0,0,1))\r
+ vertices[i].rotateXZBy(90);\r
+ if(dir == v3s16(0,0,-1))\r
+ vertices[i].rotateXZBy(-90);\r
+ if(dir == v3s16(0,-1,0))\r
+ vertices[i].rotateXYBy(-90);\r
+ if(dir == v3s16(0,1,0))\r
+ vertices[i].rotateXYBy(90);\r
+\r
+ vertices[i] += npf;\r
+ }\r
+\r
+ core::aabbox3d<f32> box;\r
+\r
+ box = core::aabbox3d<f32>(vertices[0]);\r
+ box.addInternalPoint(vertices[1]);\r
+\r
+ if(distance < mindistance)\r
+ {\r
+ if(box.intersectsWithLine(shootline))\r
+ {\r
+ nodefound = true;\r
+ nodepos = np;\r
+ neighbourpos = np;\r
+ mindistance = distance;\r
+ nodehilightbox = box;\r
+ }\r
+ }\r
+ }\r
/*\r
Regular blocks\r
*/\r
static float dig_time = 0.0;\r
static u16 dig_index = 0;\r
\r
- // Visualize selection\r
+ /*\r
+ Visualize selection\r
+ */\r
\r
hilightboxes.push_back(nodehilightbox);\r
\r
- // Handle digging\r
+ /*\r
+ TODO:\r
+ Check information text of node\r
+ */\r
+\r
+ /*\r
+ Handle digging\r
+ */\r
\r
if(g_input->getLeftReleased())\r
{\r
n.setLight(bank, 0);
}
+ /*
+ If node lets sunlight through and is under sunlight, it has
+ sunlight too.
+ */
+ if(node_under_sunlight && content_features(n.d).sunlight_propagates)
+ {
+ n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+ }
+
/*
Set the node on the map
*/
setNode(p, n);
/*
- If node is under sunlight, take all sunlighted nodes under
- it and clear light from them and from where the light has
- been spread.
+ If node is under sunlight and doesn't let sunlight through,
+ take all sunlighted nodes under it and clear light from them
+ and from where the light has been spread.
TODO: This could be optimized by mass-unlighting instead
of looping
*/
- if(node_under_sunlight)
+ if(node_under_sunlight && !content_features(n.d).sunlight_propagates)
{
s16 y = p.Y - 1;
for(;; y--){
break;
}
}
-
+
for(s32 i=0; i<2; i++)
{
enum LightBank bank = banks[i];
//dstream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
}
+NodeMetadata* Map::getNodeMetadataClone(v3s16 p)
+{
+ v3s16 blockpos = getNodeBlockPos(p);
+ v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
+ MapBlock *block = getBlockNoCreateNoEx(blockpos);
+ if(block == NULL)
+ return NULL;
+ NodeMetadata *meta = block->m_node_metadata.getClone(p_rel);
+ return meta;
+}
+
/*
ServerMap
*/
#include "constants.h"
#include "voxel.h"
#include "mapchunk.h"
+#include "nodemetadata.h"
#define MAPTYPE_BASE 0
#define MAPTYPE_SERVER 1
void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
+ /*
+ Node metadata
+ These are basically coordinate wrappers to MapBlock
+ */
+
+ NodeMetadata* getNodeMetadataClone(v3s16 p);
+
/*
Variables
*/
{
video::SColor c(255,255,255,255);
+ // Wall at X+ of node
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
// Add to mesh collector
collector.append(material, vertices, 4, indices, 6);
}
+ /*
+ Signs on walls
+ */
+ if(n.d == CONTENT_SIGN_WALL)
+ {
+ u8 l = decode_light(n.getLightBlend(daynight_ratio));
+ video::SColor c(255,l,l,l);
+
+ float d = (float)BS/16;
+ // Wall at X+ of node
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 0,0),
+ };
+
+ v3s16 dir = unpackDir(n.dir);
+
+ for(s32 i=0; i<4; i++)
+ {
+ if(dir == v3s16(1,0,0))
+ vertices[i].Pos.rotateXZBy(0);
+ if(dir == v3s16(-1,0,0))
+ vertices[i].Pos.rotateXZBy(180);
+ if(dir == v3s16(0,0,1))
+ vertices[i].Pos.rotateXZBy(90);
+ if(dir == v3s16(0,0,-1))
+ vertices[i].Pos.rotateXZBy(-90);
+ if(dir == v3s16(0,-1,0))
+ vertices[i].Pos.rotateXYBy(-90);
+ if(dir == v3s16(0,1,0))
+ vertices[i].Pos.rotateXYBy(90);
+
+ vertices[i].Pos += intToFloat(p + getPosRelative(), BS);
+ }
+
+ // Set material
+ video::SMaterial material;
+ material.setFlag(video::EMF_LIGHTING, false);
+ material.setFlag(video::EMF_BACK_FACE_CULLING, false);
+ material.setFlag(video::EMF_BILINEAR_FILTER, false);
+ material.setFlag(video::EMF_FOG_ENABLE, true);
+ //material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+ material.MaterialType
+ = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+
+ material.setTexture(0,
+ g_texturesource->getTextureRaw("sign_wall.png"));
+
+ u16 indices[] = {0,1,2,2,3,0};
+ // Add to mesh collector
+ collector.append(material, vertices, 4, indices, 6);
+ }
/*
Add flowing water to mesh
*/
#include "constants.h"
#include "mapblockobject.h"
#include "voxel.h"
+#include "nodemetadata.h"
// Named by looking towards z+
enum{
JMutex mesh_mutex;
#endif
+ NodeMetadataList m_node_metadata;
+
private:
/*
Private member variables
// Whether day and night lighting differs
bool m_day_night_differs;
- /*
- Whether everything that is mainly located on this block has
- been added to the world.
-
- While this is false, a block can still be changed a bit when
- stuff is added to the neighboring blocks that extends to this
- one.
-
- When this is false on every one of a 3x3x3 chunk of blocks, the
- central one will not be changed by the map generator in the
- future.
-
- TODO: Save in file
- */
- //bool m_not_fully_generated;
-
MapBlockObjectList m_objects;
// Object spawning stuff
float m_spawn_timer;
-
+
#ifndef SERVER // Only on client
/*
Set to true if the mesh has been ordered to be updated
}
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+ // Deprecated
i = CONTENT_COALSTONE;
f = &g_content_features[i];
//f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
f->wall_mounted = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+ i = CONTENT_FURNACE;
+ f = &g_content_features[i];
+ f->setAllTextures("furnace_side.png");
+ f->setTexture(2, "furnace_front.png");
+ f->setInventoryTexture("furnace_front.png");
+ f->param_type = CPT_NONE;
+ f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+
+ i = CONTENT_SIGN_WALL;
+ f = &g_content_features[i];
+ f->setInventoryTexture("sign_wall.png");
+ f->param_type = CPT_LIGHT;
+ f->light_propagates = true;
+ f->sunlight_propagates = true;
+ f->solidness = 0; // drawn separately, makes no faces
+ f->walkable = false;
+ f->wall_mounted = true;
+ f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+
}
TileSpec MapNode::getTile(v3s16 dir)
#define CONTENT_COALSTONE 11
#define CONTENT_WOOD 12
#define CONTENT_SAND 13
-
-/*
- This is used by all kinds of things to allocate memory for all
- contents except CONTENT_AIR and CONTENT_IGNORE
-*/
-#define USEFUL_CONTENT_COUNT 14
+#define CONTENT_FURNACE 14
+#define CONTENT_SIGN_WALL 15
/*
Content feature list
g_material_properties[CONTENT_SAND].setDiggingProperties("",
DiggingProperties(true, 0.4, 0));
+ setStoneLikeDiggingProperties(CONTENT_FURNACE, 1.0);
+
/*
Add MesePick to everything
*/
/*
Give materials
*/
+
+ // CONTENT_IGNORE-terminated list
+ u8 material_items[] = {
+ CONTENT_TORCH,
+ CONTENT_MUD,
+ CONTENT_STONE,
+ CONTENT_SAND,
+ CONTENT_TREE,
+ CONTENT_LEAVES,
+ CONTENT_MESE,
+ CONTENT_WATERSOURCE,
+ CONTENT_CLOUD,
+ CONTENT_FURNACE,
+ CONTENT_SIGN_WALL,
+ CONTENT_IGNORE
+ };
+
+ u8 *mip = material_items;
+ for(u16 i=0; i<PLAYER_INVENTORY_SIZE; i++)
+ {
+ if(*mip == CONTENT_IGNORE)
+ break;
+
+ InventoryItem *item = new MaterialItem(*mip, 1);
+ player->inventory.addItem("main", item);
+
+ mip++;
+ }
+
+#if 0
assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE);
// add torch first
InventoryItem *item = new MaterialItem(i, 1);
player->inventory.addItem("main", item);
}
+#endif
+
// Sign
{
InventoryItem *item = new MapBlockObjectItem("Sign Example text");