for many people. The old build system is still included, but it's not
documented anywhere.
- You need CMake, Irrlicht, Zlib and Visual Studio or MinGW
+ - you can get zlibwapi.lib from a file called zlib125dll.zip
- NOTE: Probably it will not work easily and you will need to fix some stuff.
- Steps:
- Start up the CMake GUI
#enable_fog = true
#new_style_water = true
+#new_style_leaves = true
# Server side stuff
RelativePath=".\src\guiTextInputMenu.cpp"\r
>\r
</File>\r
- <File\r
- RelativePath=".\src\heightmap.cpp"\r
- >\r
- </File>\r
<File\r
RelativePath=".\src\inventory.cpp"\r
>\r
RelativePath=".\src\mineral.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\src\noise.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath=".\src\player.cpp"\r
>\r
endif(BUILD_CLIENT)
find_package(ZLIB REQUIRED)
set(PLATFORM_LIBS -lpthread)
- set(CLIENT_PLATFORM_LIBS -lXxf86vm)
+ #set(CLIENT_PLATFORM_LIBS -lXxf86vm)
+ find_library(XXF86VM_LIBRARY, Xxf86vm)
+ set(CLIENT_PLATFORM_LIBS ${XXF86VM_LIBRARY})
endif()
configure_file(
// [0] u16 TOSERVER_INIT
// [2] u8 SER_FMT_VER_HIGHEST
// [3] u8[20] player_name
- SharedBuffer<u8> data(2+1+20);
+ SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE);
writeU16(&data[0], TOSERVER_INIT);
writeU8(&data[2], SER_FMT_VER_HIGHEST);
- memcpy(&data[3], myplayer->getName(), 20);
+ memset((char*)&data[3], 0, PLAYERNAME_SIZE);
+ snprintf((char*)&data[3], PLAYERNAME_SIZE, "%s", myplayer->getName());
// Send as unreliable
Send(0, data, false);
}
void set_default_settings()
{
+ // Client and server
+ g_settings.setDefault("footprints", "false");
+
// Client stuff
g_settings.setDefault("wanted_fps", "30");
g_settings.setDefault("fps_max", "60");
g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
g_settings.setDefault("enable_fog", "true");
g_settings.setDefault("new_style_water", "true");
- g_settings.setDefault("terrain_viewer", "false");
+ g_settings.setDefault("new_style_leaves", "true");
g_settings.setDefault("free_move", "false");
g_settings.setDefault("continuous_forward", "false");
/*
Apply water resistance
*/
- if(player->in_water)
+ if(player->in_water_stable)
{
- f32 max_down = 1.0*BS;
+ f32 max_down = 1.5*BS;
if(speed.Y < -max_down) speed.Y = -max_down;
f32 max = 2.5*BS;
/*
Add footsteps to grass
*/
- // Get node that is at BS/4 under player
- v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0));
- try{
- MapNode n = m_map->getNode(bottompos);
- if(n.d == CONTENT_GRASS)
- {
- n.d = CONTENT_GRASS_FOOTSTEPS;
- m_map->setNode(bottompos, n);
-#ifndef SERVER
- // Update mesh on client
- if(m_map->mapType() == MAPTYPE_CLIENT)
+ if(g_settings.getBool("footprints"))
+ {
+ // Get node that is at BS/4 under player
+ v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0));
+ try{
+ MapNode n = m_map->getNode(bottompos);
+ if(n.d == CONTENT_GRASS)
{
- v3s16 p_blocks = getNodeBlockPos(bottompos);
- MapBlock *b = m_map->getBlockNoCreate(p_blocks);
- b->updateMesh(m_daynight_ratio);
- }
+ n.d = CONTENT_GRASS_FOOTSTEPS;
+ m_map->setNode(bottompos, n);
+#ifndef SERVER
+ // Update mesh on client
+ if(m_map->mapType() == MAPTYPE_CLIENT)
+ {
+ v3s16 p_blocks = getNodeBlockPos(bottompos);
+ MapBlock *b = m_map->getBlockNoCreate(p_blocks);
+ b->updateMesh(m_daynight_ratio);
+ }
#endif
+ }
+ }
+ catch(InvalidPositionException &e)
+ {
}
- }
- catch(InvalidPositionException &e)
- {
}
}
}
case 257: // Start game
acceptInput();
quitMenu();
- break;
+ return true;
case 260: // Delete map
// Don't accept input data, just set deletion request
m_data->delete_map = true;
m_accepted = true;
quitMenu();
- break;
+ return true;
}
}
if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
case 256: case 257: case 258:
acceptInput();
quitMenu();
- break;
+ return true;
}
}
}
case 257:
m_status = true;
quitMenu();
- break;
+ return true;
}
}
}
{\r
case 256: // continue\r
quitMenu();\r
- break;\r
+ // ALWAYS return immediately after quitMenu()\r
+ return true;\r
case 260: // disconnect\r
m_gamecallback->disconnect();\r
quitMenu();\r
- break;\r
+ return true;\r
case 257: // exit\r
m_gamecallback->exitToOS();\r
quitMenu();\r
- break;\r
+ return true;\r
}\r
}\r
}\r
case 257:
acceptInput();
quitMenu();
- break;
+ // quitMenu deallocates menu
+ return true;
}
}
if(event.GUIEvent.EventType==gui::EGET_EDITBOX_ENTER)
case 256:
acceptInput();
quitMenu();
- break;
+ // quitMenu deallocates menu
+ return true;
}
}
}
Build system / running:\r
-----------------------\r
\r
-NOTE: The following fixme is not apparently valid, and it does work.\r
-FIXME: Graphical mode seems to segfault with Irrlicht 1.7.1 on 64-bit\r
- systems. (Ubuntu)\r
- - http://pastebin.no/32bo\r
- - Might be just a bad build, too\r
- - Doesn't affect Irrlicht 1.7.2 or 32-bit 1.7.1. (Arch/Debian)\r
- - A similar error occurs when getTexture is called from a thread\r
- when the texture has not been already loaded from disk:\r
- http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?p=68830\r
-\r
FIXME: Some network errors on Windows that cause local game to not work\r
- See siggjen's emails.\r
- Is this the famous "windows 7 problem"?\r
+ - Apparently there might be other errors too\r
+ - There is some problem with the menu system, something like the\r
+ .Parent of guiPauseMenu to end up being 0xfeeefeee\r
\r
Networking and serialization:\r
-----------------------------\r
TODO: Remove duplicate lighting implementation from Map (leave\r
VoxelManipulator, which is faster)\r
\r
-FEATURE: Map generator version 2\r
- - Create a system that allows a huge amount of different "map\r
- generator modules/filters"\r
-\r
-FEATURE: The map could be generated procedually:\r
- - This would need the map to be generated in larger pieces\r
- - How large? How do they connect to each other?\r
- - It has to be split vertically also\r
- - Lighting would not have to be necessarily calculated until\r
- the blocks are actually needed - it would be quite fast\r
- - Something like 64*64*16 MapBlocks?\r
- - No, MapSectors. And as much as it is efficient to do,\r
- 64x64 might be too much.\r
- - FIXME: This is currently halfway done and the generator is\r
- fairly broken\r
- * Make the stone level with a heightmap\r
- * Carve out stuff in the stone\r
- * Dump dirt all around, and simulate it falling off steep\r
- places\r
- * Erosion simulation at map generation time\r
+FEATURE: Create a system that allows a huge amount of different "map\r
+ generator modules/filters"\r
+\r
+FEATURE: Erosion simulation at map generation time\r
- Simulate water flows, which would carve out dirt fast and\r
then turn stone into gravel and sand and relocate it.\r
- How about relocating minerals, too? Coal and gold in\r
- map/meta.txt, which should contain only plain text, something like this:\r
seed = 7ff1bafcd7118800\r
chunksize = 8\r
- - map/chunks.dat\r
-* Save chunk metadata on disk\r
+ - map/chunks.dat: chunk positions and flags in binary format\r
* Make server find the spawning place from the real map data, not from\r
the heightmap\r
- But the changing borders of chunk have to be avoided, because\r
* Check the fixmes in the list above\r
\r
=== Stuff to do after release\r
-* Set backface culling on, especially for water\r
* Add some kind of erosion and other stuff that now is possible\r
* Make client to fetch stuff asynchronously\r
- Needs method SyncProcessData\r
* Water doesn't start flowing after map generation like it should\r
- Are there still problems?\r
* Better water generation (spread it to underwater caverns but don't\r
- fill dungeons that don't touch outside air)\r
+ fill dungeons that don't touch big water masses)\r
* When generating a chunk and the neighboring chunk doesn't have mud\r
and stuff yet and the ground is fairly flat, the mud will flow to\r
the other chunk making nasty straight walls when the other chunk\r
continue;\r
}\r
\r
- std::cout<<DTIME<<"Connecting to server..."<<std::endl;\r
+ dstream<<DTIME<<"Connecting to server at ";\r
+ connect_address.print(&dstream);\r
+ dstream<<std::endl;\r
client.connect(connect_address);\r
\r
try{\r
u32 loopcount = 0;
u32 initial_size = m_transforming_liquid.size();
- if(initial_size != 0)
- dstream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;
+ /*if(initial_size != 0)
+ dstream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
while(m_transforming_liquid.size() != 0)
{
p1.Y -= 1;
VoxelArea leaves_a(v3s16(-2,-2,-2), v3s16(2,2,2));
- SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
+ //SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
+ Buffer<u8> leaves_d(leaves_a.getVolume());
for(s32 i=0; i<leaves_a.getVolume(); i++)
leaves_d[i] = 0;
double noise = noise2d_perlin(
0.5+(float)p.X/250, 0.5+(float)p.Y/250,
seed+2, 5, 0.6);
- double zeroval = -0.4;
+ double zeroval = -0.3;
if(noise < zeroval)
return 0;
else
{
// The base ground level
double base = WATER_LEVEL - 4.0 + 25. * noise2d_perlin(
- 0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
- seed, 6, 0.6);
-
+ 0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
+ (seed>>32)+654879876, 6, 0.6);
+ /*// A bit hillier one
+ double base2 = WATER_LEVEL - 4.0 + 40. * noise2d_perlin(
+ 0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
+ (seed>>27)+90340, 6, 0.69);
+ if(base2 > base)
+ base = base2;*/
+#if 1
// Higher ground level
- double higher = WATER_LEVEL + 23. + 30. * noise2d_perlin(
+ double higher = WATER_LEVEL + 13. + 50. * noise2d_perlin(
0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
seed+85039, 6, 0.69);
//higher = 30; // For debugging
// Limit higher to at least base
if(higher < base)
higher = base;
-
+
// Steepness factor of cliffs
double b = 1.0 + 1.0 * noise2d_perlin(
0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
seed-932, 7, 0.7);
b = rangelim(b, 0.0, 1000.0);
- // Make steep stuff very steep and non-steep stuff very non-steep
- b = pow(b, 4);
- b *= 10;
+ b = pow(b, 5);
+ b *= 7;
+ b = rangelim(b, 3.0, 1000.0);
+ //dstream<<"b="<<b<<std::endl;
//double b = 20;
+ // Offset to more low
+ double a_off = -0.3;
// High/low selector
- double a = 0.5 + b * noise2d_perlin(
+ /*double a = 0.5 + b * (a_off + noise2d_perlin(
0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
- seed-359, 6, 0.7);
+ seed-359, 6, 0.7));*/
+ double a = 0.5 + b * (a_off + noise2d_perlin(
+ 0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
+ seed-359, 5, 0.60));
+ // Limit
a = rangelim(a, 0.0, 1.0);
//dstream<<"a="<<a<<std::endl;
double h = base*(1.0-a) + higher*a;
-
+#else
+ double h = base;
+#endif
return h;
}
/*
Make dungeons
*/
- u32 dungeons_count = relative_volume / 600000;
- u32 bruises_count = relative_volume * stone_surface_max_y / 40000000;
+ //u32 dungeons_count = relative_volume / 600000;
+ /*u32 bruises_count = relative_volume * stone_surface_max_y / 40000000;
if(stone_surface_max_y < WATER_LEVEL)
- bruises_count = 0;
- //dungeons_count = 0;
- //bruises_count = 0;
+ bruises_count = 0;*/
+ u32 dungeons_count = 0;
+ u32 bruises_count = 0;
for(u32 jj=0; jj<dungeons_count+bruises_count; jj++)
{
s16 min_tunnel_diameter = 2;
//s16 si2 = rs - MYMAX(0, maxabsxz-rs/4);
s16 si2 = rs - MYMAX(0, maxabsxz-rs/7);
//s16 si2 = rs - abs(x0);
- for(s16 y0=-si2+1; y0<=si2-1; y0++)
+ for(s16 y0=-si2+1+1; y0<=si2-1; y0++)
{
s16 z = cp.Z + z0;
s16 y = cp.Y + y0;
m_seed+1, 3, 0.55));
// Find ground level
- s16 surface_y = find_ground_level(vmanip, p2d);
+ s16 surface_y = find_ground_level_clever(vmanip, p2d);
/*
If topmost node is grass, change it to mud.
0.5+(float)p2d.X/500, 0.5+(float)p2d.Y/500,
m_seed+59420, 3, 0.50);
- bool have_sand = (sandnoise > 0.0);
+ bool have_sand = (sandnoise > -0.15);
if(have_sand == false)
continue;
v3f vertex_pos[4];
// If looking towards z+, this is the face that is behind
// the center point, facing towards z+.
- vertex_pos[0] = v3f( BS/2,-BS/2,BS/2);
- vertex_pos[1] = v3f(-BS/2,-BS/2,BS/2);
- vertex_pos[2] = v3f(-BS/2, BS/2,BS/2);
- vertex_pos[3] = v3f( BS/2, BS/2,BS/2);
+ vertex_pos[0] = v3f(-BS/2,-BS/2,BS/2);
+ vertex_pos[1] = v3f( BS/2,-BS/2,BS/2);
+ vertex_pos[2] = v3f( BS/2, BS/2,BS/2);
+ vertex_pos[3] = v3f(-BS/2, BS/2,BS/2);
if(dir == v3s16(0,0,1))
{
JMutexAutoLock lock(m_temp_mods_mutex);
m_temp_mods.copy(temp_mods);
}
-
+
+ /*
+ Some settings
+ */
bool new_style_water = g_settings.getBool("new_style_water");
+ bool new_style_leaves = g_settings.getBool("new_style_leaves");
+
float node_water_level = 1.0;
if(new_style_water)
node_water_level = 0.9;
material.BackfaceCulling = false;
material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
+ //material.setFlag(video::EMF_ANTI_ALIASING, video::EAAM_SIMPLE);
material.setFlag(video::EMF_FOG_ENABLE, true);
for(u32 i=0; i<fastfaces_new.size(); i++)
continue;
material.setTexture(0, texture);
- if(f.tile.alpha != 255)
+
+ f.tile.applyMaterialOptions(material);
+
+ /*if(f.tile.alpha != 255)
material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
else
- material.MaterialType = video::EMT_SOLID;
+ material.MaterialType = video::EMT_SOLID;*/
collector.append(material, f.vertices, 4, indices, 6);
}
//TimeTaker timer2("updateMesh() adding special stuff");
// Flowing water material
- video::SMaterial material_w1;
- material_w1.setFlag(video::EMF_LIGHTING, false);
- material_w1.setFlag(video::EMF_BACK_FACE_CULLING, false);
- material_w1.setFlag(video::EMF_BILINEAR_FILTER, false);
- material_w1.setFlag(video::EMF_FOG_ENABLE, true);
- material_w1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
- material_w1.setTexture(0,
- g_irrlicht->getTexture("water.png"));
+ video::SMaterial material_water1;
+ material_water1.setFlag(video::EMF_LIGHTING, false);
+ material_water1.setFlag(video::EMF_BACK_FACE_CULLING, false);
+ material_water1.setFlag(video::EMF_BILINEAR_FILTER, false);
+ material_water1.setFlag(video::EMF_FOG_ENABLE, true);
+ material_water1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
+ material_water1.setTexture(0, g_irrlicht->getTexture("water.png"));
+
+ // New-style leaves material
+ video::SMaterial material_leaves1;
+ material_leaves1.setFlag(video::EMF_LIGHTING, false);
+ //material_leaves1.setFlag(video::EMF_BACK_FACE_CULLING, false);
+ material_leaves1.setFlag(video::EMF_BILINEAR_FILTER, false);
+ material_leaves1.setFlag(video::EMF_FOG_ENABLE, true);
+ material_leaves1.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+ material_leaves1.setTexture(0, g_irrlicht->getTexture("leaves.png"));
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
- collector.append(material_w1, vertices, 4, indices, 6);
+ collector.append(material_water1, vertices, 4, indices, 6);
}
/*
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
- collector.append(material_w1, vertices, 4, indices, 6);
+ collector.append(material_water1, vertices, 4, indices, 6);
}
}
/*
- Add water sources to mesh
+ Add water sources to mesh if using new style
*/
else if(n.d == CONTENT_WATERSOURCE && new_style_water)
{
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
- collector.append(material_w1, vertices, 4, indices, 6);
+ collector.append(material_water1, vertices, 4, indices, 6);
+ }
+ /*
+ Add leaves if using new style
+ */
+ else if(n.d == CONTENT_LEAVES && new_style_leaves)
+ {
+ u8 l = decode_light(n.getLightBlend(daynight_ratio));
+ video::SColor c(255,l,l,l);
+
+ for(u32 j=0; j<6; j++)
+ {
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, 0,0),
+ };
+
+ if(j == 0)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(0);
+ }
+ else if(j == 1)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(180);
+ }
+ else if(j == 2)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(-90);
+ }
+ else if(j == 3)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(90);
+ }
+ else if(j == 4)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateYZBy(-90);
+ }
+ else if(j == 5)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateYZBy(90);
+ }
+
+ for(u16 i=0; i<4; i++)
+ {
+ vertices[i].Pos += intToFloat(p + getPosRelative());
+ }
+
+ u16 indices[] = {0,1,2,2,3,0};
+ // Add to mesh collector
+ collector.append(material_leaves1, vertices, 4, indices, 6);
+ }
}
}
void init_mapnode(IIrrlichtWrapper *irrlicht)
{
+ bool new_style_water = g_settings.getBool("new_style_water");
+ bool new_style_leaves = g_settings.getBool("new_style_leaves");
+
u8 i;
ContentFeatures *f = NULL;
i = CONTENT_LEAVES;
f = &g_content_features[i];
- f->setAllTextures(irrlicht->getTextureId("leaves.png"));
- f->param_type = CPT_MINERAL;
+ f->light_propagates = true;
+ //f->param_type = CPT_MINERAL;
+ f->param_type = CPT_LIGHT;
f->is_ground_content = true;
+ if(new_style_leaves)
+ {
+ f->solidness = 0; // drawn separately, makes no faces
+ }
+ else
+ {
+ f->setAllTextures(irrlicht->getTextureId("leaves.png"));
+ }
+ /*{
+ TileSpec t;
+ t.spec = TextureSpec(irrlicht->getTextureId("leaves.png"));
+ //t.material_type = MATERIAL_ALPHA_SIMPLE;
+ //t.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
+ f->setAllTiles(t);
+ }*/
i = CONTENT_COALSTONE;
f = &g_content_features[i];
f->buildable_to = true;
f->liquid_type = LIQUID_FLOWING;
- bool new_style_water = g_settings.getBool("new_style_water");
-
i = CONTENT_WATERSOURCE;
f = &g_content_features[i];
- //f->setTexture(0, irrlicht->getTextureId("water.png"), WATER_ALPHA);
- if(new_style_water == false)
- f->setAllTextures(irrlicht->getTextureId("water.png"), WATER_ALPHA);
f->setInventoryTexture(irrlicht->getTextureId("water.png"));
+ if(new_style_water)
+ {
+ f->solidness = 0; // drawn separately, makes no faces
+ }
+ else // old style
+ {
+ f->setAllTextures(irrlicht->getTextureId("water.png"), WATER_ALPHA);
+ TileSpec t;
+ t.spec = TextureSpec(irrlicht->getTextureId("water.png"));
+ t.alpha = WATER_ALPHA;
+ t.material_type = MATERIAL_ALPHA_VERTEX;
+ t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
+ f->setAllTiles(t);
+ f->solidness = 1;
+ }
f->param_type = CPT_LIGHT;
f->light_propagates = true;
- f->solidness = 1;
f->walkable = false;
f->pointable = false;
f->diggable = false;
~ContentFeatures();
+ // Quickhands for simple materials
+ void setTexture(u16 i, const TextureSpec &spec, u8 alpha=255)
+ {
+ tiles[i].spec = spec;
+ if(alpha != 255)
+ {
+ tiles[i].alpha = alpha;
+ tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
+ }
+ }
void setAllTextures(const TextureSpec &spec, u8 alpha=255)
{
for(u16 i=0; i<6; i++)
{
- tiles[i].spec = spec;
- tiles[i].alpha = alpha;
+ setTexture(i, spec, alpha);
}
// Set this too so it can be left as is most times
- /*if(inventory_image_path == "")
- inventory_image_path = porting::getDataPath(imgname.c_str());*/
-
if(inventory_texture.empty())
inventory_texture = spec;
}
- void setTexture(u16 i, const TextureSpec &spec, u8 alpha=255)
+
+ void setTile(u16 i, const TileSpec &tile)
{
- tiles[i].spec = spec;
- tiles[i].alpha = alpha;
+ tiles[i] = tile;
+ }
+ void setAllTiles(const TileSpec &tile)
+ {
+ for(u16 i=0; i<6; i++)
+ {
+ setTile(i, tile);
+ }
}
void setInventoryTexture(const TextureSpec &spec)
union
{
- u8 param2;
-
/*
- Direction for torches and other stuff.
- Format is freeform. e.g. packDir or encode_dirs can be used.
+ The second parameter. Initialized to 0.
+ Direction for torches and flowing water.
*/
+ u8 param2;
u8 dir;
};
}
/*
- This should be called when the menu wants to quit
+ This should be called when the menu wants to quit.
+
+ WARNING: THIS DEALLOCATES THE MENU FROM MEMORY. Return
+ immediately if you call this from the menu itself.
*/
void quitMenu()
{
Player::Player():
touching_ground(false),
in_water(false),
+ in_water_stable(false),
+ swimming_up(false),
peer_id(PEER_ID_INEXISTENT),
+ m_pitch(0),
+ m_yaw(0),
m_speed(0,0,0),
m_position(0,0,0)
{
position += m_speed * dtime;
bool free_move = g_settings.getBool("free_move");
- bool terrain_viewer = g_settings.getBool("terrain_viewer");
// Skip collision detection if player is non-local or
// a special movement mode is used
- if(isLocal() == false || free_move || terrain_viewer)
+ if(isLocal() == false || free_move)
{
setPosition(position);
return;
v3s16 pos_i = floatToInt(position);
/*
- Check if player is in water
+ Check if player is in water (the oscillating value)
*/
try{
if(in_water)
in_water = false;
}
+ /*
+ Check if player is in water (the stable value)
+ */
+ try{
+ v3s16 pp = floatToInt(position + v3f(0,0,0));
+ in_water_stable = content_liquid(map.getNode(pp).d);
+ }
+ catch(InvalidPositionException &e)
+ {
+ in_water_stable = false;
+ }
+
// The frame length is limited to the player going 0.1*BS per call
f32 d = (float)BS * 0.15;
speed.Y = 6.5*BS;
setSpeed(speed);
}
+ // Use the oscillating value for getting out of water
+ // (so that the player doesn't fly on the surface)
else if(in_water)
{
v3f speed = getSpeed();
- speed.Y = 2.0*BS;
+ speed.Y = 1.5*BS;
setSpeed(speed);
swimming_up = true;
}
void deSerialize(std::istream &is);
bool touching_ground;
+ // This oscillates so that the player jumps a bit above the surface
bool in_water;
+ // This is more stable and defines the maximum speed of the player
+ bool in_water_stable;
bool swimming_up;
Inventory inventory;
#include <unistd.h>
char buf[BUFSIZ];
+ memset(buf, 0, BUFSIZ);
// Get path to executable
- readlink("/proc/self/exe", buf, BUFSIZ);
+ readlink("/proc/self/exe", buf, BUFSIZ-1);
pathRemoveFile(buf, '/');
#include <unistd.h>
char buf[BUFSIZ];
+ memset(buf, 0, BUFSIZ);
// Get path to executable
- readlink("/proc/self/exe", buf, BUFSIZ);
+ readlink("/proc/self/exe", buf, BUFSIZ-1);
pathRemoveFile(buf, '/');
{
(*s)<<id<<": ";
(*s)<<"\""<<name<<"\" ("
- <<position.X<<","<<position.Y
- <<","<<position.Z<<") ";
+ <<(position.X/10)<<","<<(position.Y/10)
+ <<","<<(position.Z/10)<<") ";
address.print(s);
(*s)<<" avg_rtt="<<avg_rtt;
(*s)<<std::endl;
"peer_id="<<player->peer_id<<std::endl;*/
writeU16(&data[start], player->peer_id);
+ memset((char*)&data[start+2], 0, PLAYERNAME_SIZE);
snprintf((char*)&data[start+2], PLAYERNAME_SIZE, "%s", player->getName());
start += 2+PLAYERNAME_SIZE;
}
#if 1
player->setPosition(intToFloat(v3s16(
0,
- 40, //64,
+ 45, //64,
0
)));
#endif
#include "texture.h"
#include <string>
+enum MaterialType{
+ MATERIAL_ALPHA_NONE,
+ MATERIAL_ALPHA_VERTEX,
+ MATERIAL_ALPHA_SIMPLE, // >127 = opaque
+ MATERIAL_ALPHA_BLEND,
+};
+
+// Material flags
+#define MATERIAL_FLAG_BACKFACE_CULLING 0x01
+
+/*
+ This fully defines the looks of a tile.
+ The SMaterial of a tile is constructed according to this.
+*/
struct TileSpec
{
TileSpec():
- alpha(255)
+ alpha(255),
+ material_type(MATERIAL_ALPHA_NONE),
+ material_flags(
+ MATERIAL_FLAG_BACKFACE_CULLING
+ )
{
}
bool operator==(TileSpec &other)
{
- return (spec == other.spec && alpha == other.alpha);
+ return (
+ spec == other.spec &&
+ alpha == other.alpha &&
+ material_type == other.material_type &&
+ material_flags == other.material_flags
+ );
}
- TextureSpec spec;
- u8 alpha;
-};
-
-#if 0
-struct TileSpec
-{
- TileSpec():
- alpha(255)
+ // Sets everything else except the texture in the material
+ void applyMaterialOptions(video::SMaterial &material)
{
- }
+ if(alpha != 255 && material_type != MATERIAL_ALPHA_VERTEX)
+ dstream<<"WARNING: TileSpec: alpha != 255 "
+ "but not MATERIAL_ALPHA_VERTEX"
+ <<std::endl;
- TileSpec(const std::string &a_name):
- name(a_name),
- alpha(255)
- {
- }
+ if(material_type == MATERIAL_ALPHA_NONE)
+ material.MaterialType = video::EMT_SOLID;
+ else if(material_type == MATERIAL_ALPHA_VERTEX)
+ material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
+ else if(material_type == MATERIAL_ALPHA_SIMPLE)
+ material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+ else if(material_type == MATERIAL_ALPHA_BLEND)
+ material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- TileSpec(const char *a_name):
- name(a_name),
- alpha(255)
- {
- }
-
- bool operator==(TileSpec &other)
- {
- return (name == other.name && alpha == other.alpha);
+ material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) ? true : false;
}
- // path + mods
- std::string name;
+ // Specification of texture
+ TextureSpec spec;
+ // Vertex alpha
u8 alpha;
+ // Material type
+ u8 material_type;
+ // Material flags
+ u8 material_flags;
};
-#endif
#endif
n = m_defaults.find(name);
if(n == NULL)
{
+ dstream<<"INFO: Settings: Setting not found: \""
+ <<name<<"\""<<std::endl;
throw SettingNotFoundException("Setting not found");
}
}