Merge remote-tracking branch 'origin/upstream'

This commit is contained in:
Nils Dagsson Moskopp 2011-07-30 18:53:54 +02:00
commit 4ef9c7675a
35 changed files with 2817 additions and 2103 deletions

BIN
data/junglegrass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

BIN
data/jungletree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

BIN
data/jungletree_top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

113
po/en/minetest.pot Normal file

@ -0,0 +1,113 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-07-24 11:32+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiMainMenu.cpp:180
msgid "Name/Password"
msgstr ""
#: src/guiMainMenu.cpp:203
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:223
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:230
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:236
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:244
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:253
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:276
msgid "Creative Mode"
msgstr ""
#: src/guiMainMenu.cpp:282
msgid "Enable Damage"
msgstr ""
#: src/guiMainMenu.cpp:290
msgid "Delete map"
msgstr ""
#: src/guiMessageMenu.cpp:93 src/guiTextInputMenu.cpp:111
msgid "Proceed"
msgstr ""
#: src/guiPasswordChange.cpp:102
msgid "Old Password"
msgstr ""
#: src/guiPasswordChange.cpp:117
msgid "New Password"
msgstr ""
#: src/guiPasswordChange.cpp:131
msgid "Confirm Password"
msgstr ""
#: src/guiPasswordChange.cpp:146
msgid "Change"
msgstr ""
#: src/guiPasswordChange.cpp:155
msgid "Passwords do not match!"
msgstr ""
#: src/guiPauseMenu.cpp:110
msgid "Continue"
msgstr ""
#: src/guiPauseMenu.cpp:117
msgid "Change Password"
msgstr ""
#: src/guiPauseMenu.cpp:124
msgid "Disconnect"
msgstr ""
#: src/guiPauseMenu.cpp:131
msgid "Exit to OS"
msgstr ""
#: src/guiPauseMenu.cpp:138
msgid ""
"Keys:\n"
"- WASD: Walk\n"
"- Mouse left: dig blocks\n"
"- Mouse right: place blocks\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Inventory menu\n"
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""

@ -78,7 +78,8 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
{
try{
// Object collides into walkable nodes
if(content_walkable(map->getNode(v3s16(x,y,z)).d) == false)
MapNode n = map->getNode(v3s16(x,y,z));
if(content_features(n).walkable == false)
continue;
}
catch(InvalidPositionException &e)

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventory.h"
#include "content_mapnode.h"
#include "player.h"
#include "mapnode.h" // For content_t
/*
items: actually *items[9]
@ -446,7 +447,7 @@ void craft_set_creative_inventory(Player *player)
*/
// CONTENT_IGNORE-terminated list
u8 material_items[] = {
content_t material_items[] = {
CONTENT_TORCH,
CONTENT_COBBLE,
CONTENT_MUD,
@ -472,7 +473,7 @@ void craft_set_creative_inventory(Player *player)
CONTENT_IGNORE
};
u8 *mip = material_items;
content_t *mip = material_items;
for(u16 i=0; i<PLAYER_INVENTORY_SIZE; i++)
{
if(*mip == CONTENT_IGNORE)

@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//#include "serverobject.h"
#include "content_sao.h"
bool item_material_is_cookable(u8 content)
bool item_material_is_cookable(content_t content)
{
if(content == CONTENT_TREE)
return true;
@ -34,7 +34,7 @@ bool item_material_is_cookable(u8 content)
return false;
}
InventoryItem* item_material_create_cook_result(u8 content)
InventoryItem* item_material_create_cook_result(content_t content)
{
if(content == CONTENT_TREE)
return new CraftItem("lump_of_coal", 1);

@ -22,13 +22,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" // For u8, s16
#include <string>
#include "mapnode.h" // For content_t
class InventoryItem;
class ServerActiveObject;
class ServerEnvironment;
bool item_material_is_cookable(u8 content);
InventoryItem* item_material_create_cook_result(u8 content);
bool item_material_is_cookable(content_t content);
InventoryItem* item_material_create_cook_result(content_t content);
std::string item_craft_get_image_name(const std::string &subname);
ServerActiveObject* item_craft_create_object(const std::string &subname,

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_mapnode.h"
#include "main.h" // For g_settings and g_texturesource
#include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor()
#ifndef SERVER
// Create a cuboid.
@ -198,6 +199,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
AtlasPointer pa_papyrus = g_texturesource->getTexture(
g_texturesource->getTextureId("papyrus.png"));
material_papyrus.setTexture(0, pa_papyrus.atlas);
// junglegrass material
video::SMaterial material_junglegrass;
material_junglegrass.setFlag(video::EMF_LIGHTING, false);
material_junglegrass.setFlag(video::EMF_BILINEAR_FILTER, false);
material_junglegrass.setFlag(video::EMF_FOG_ENABLE, true);
material_junglegrass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
AtlasPointer pa_junglegrass = g_texturesource->getTexture(
g_texturesource->getTextureId("junglegrass.png"));
material_junglegrass.setTexture(0, pa_junglegrass.atlas);
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
@ -209,7 +221,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add torches to mesh
*/
if(n.d == CONTENT_TORCH)
if(n.getContent() == CONTENT_TORCH)
{
video::SColor c(255,255,255,255);
@ -222,7 +234,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
};
v3s16 dir = unpackDir(n.dir);
v3s16 dir = unpackDir(n.param2);
for(s32 i=0; i<4; i++)
{
@ -272,10 +284,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Signs on walls
*/
else if(n.d == CONTENT_SIGN_WALL)
else if(n.getContent() == CONTENT_SIGN_WALL)
{
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16;
// Wall at X+ of node
@ -287,7 +299,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 0,0),
};
v3s16 dir = unpackDir(n.dir);
v3s16 dir = unpackDir(n.param2);
for(s32 i=0; i<4; i++)
{
@ -327,26 +339,26 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add flowing water to mesh
*/
else if(n.d == CONTENT_WATER)
else if(n.getContent() == CONTENT_WATER)
{
bool top_is_water = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
if(ntop.d == CONTENT_WATER || ntop.d == CONTENT_WATERSOURCE)
if(ntop.getContent() == CONTENT_WATER || ntop.getContent() == CONTENT_WATERSOURCE)
top_is_water = true;
u8 l = 0;
// Use the light of the node on top if possible
if(content_features(ntop.d).param_type == CPT_LIGHT)
if(content_features(ntop).param_type == CPT_LIGHT)
l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
// Otherwise use the light of this node (the water)
else
l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(WATER_ALPHA,l,l,l);
video::SColor c = MapBlock_LightColor(WATER_ALPHA, l);
// Neighbor water levels (key = relative position)
// Includes current node
core::map<v3s16, f32> neighbor_levels;
core::map<v3s16, u8> neighbor_contents;
core::map<v3s16, content_t> neighbor_contents;
core::map<v3s16, u8> neighbor_flags;
const u8 neighborflag_top_is_water = 0x01;
v3s16 neighbor_dirs[9] = {
@ -368,14 +380,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// Check neighbor
v3s16 p2 = p + neighbor_dirs[i];
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
if(n2.d != CONTENT_IGNORE)
if(n2.getContent() != CONTENT_IGNORE)
{
content = n2.d;
content = n2.getContent();
if(n2.d == CONTENT_WATERSOURCE)
if(n2.getContent() == CONTENT_WATERSOURCE)
level = (-0.5+node_water_level) * BS;
else if(n2.d == CONTENT_WATER)
level = (-0.5 + ((float)(n2.param2 & LIQUID_LEVEL_MASK) + 0.5) / 8.0
else if(n2.getContent() == CONTENT_WATER)
level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
* node_water_level) * BS;
// Check node above neighbor.
@ -383,7 +395,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// doesn't exist
p2.Y += 1;
n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER)
if(n2.getContent() == CONTENT_WATERSOURCE || n2.getContent() == CONTENT_WATER)
flags |= neighborflag_top_is_water;
}
@ -591,14 +603,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add water sources to mesh if using new style
*/
else if(n.d == CONTENT_WATERSOURCE && new_style_water)
else if(n.getContent() == CONTENT_WATERSOURCE && new_style_water)
{
//bool top_is_water = false;
bool top_is_air = false;
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
/*if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
/*if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
top_is_water = true;*/
if(n.d == CONTENT_AIR)
if(n.getContent() == CONTENT_AIR)
top_is_air = true;
/*if(top_is_water == true)
@ -607,7 +619,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
continue;
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(WATER_ALPHA,l,l,l);
video::SColor c = MapBlock_LightColor(WATER_ALPHA, l);
video::S3DVertex vertices[4] =
{
@ -638,11 +650,11 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add leaves if using new style
*/
else if(n.d == CONTENT_LEAVES && new_style_leaves)
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)));
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++)
{
@ -706,10 +718,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add glass
*/
else if(n.d == CONTENT_GLASS)
else if(n.getContent() == CONTENT_GLASS)
{
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++)
{
@ -769,10 +781,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add fence
*/
else if(n.d == CONTENT_FENCE)
else if(n.getContent() == CONTENT_FENCE)
{
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
const f32 post_rad=(f32)BS/10;
const f32 bar_rad=(f32)BS/20;
@ -795,7 +807,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 p2 = p;
p2.X++;
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
if(n2.d == CONTENT_FENCE)
if(n2.getContent() == CONTENT_FENCE)
{
pos = intToFloat(p+blockpos_nodes, BS);
pos.X += BS/2;
@ -821,7 +833,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
p2 = p;
p2.Z++;
n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
if(n2.d == CONTENT_FENCE)
if(n2.getContent() == CONTENT_FENCE)
{
pos = intToFloat(p+blockpos_nodes, BS);
pos.Z += BS/2;
@ -848,7 +860,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add stones with minerals if stone is invisible
*/
else if(n.d == CONTENT_STONE && invisible_stone && n.getMineral() != MINERAL_NONE)
else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral() != MINERAL_NONE)
{
for(u32 j=0; j<6; j++)
{
@ -856,19 +868,20 @@ 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.d).param_type == CPT_LIGHT)
if(content_features(n2).param_type == CPT_LIGHT)
l = decode_light(n2.getLightBlend(data->m_daynight_ratio));
else
l = 255;*/
u8 l = 255;
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
// Get the right texture
TileSpec ts = n.getTile(dir);
AtlasPointer ap = ts.texture;
material_general.setTexture(0, ap.atlas);
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),
@ -916,10 +929,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
}
#endif
else if(n.d == CONTENT_PAPYRUS)
else if(n.getContent() == CONTENT_PAPYRUS)
{
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
{
@ -966,10 +979,61 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
collector.append(material_papyrus, vertices, 4, indices, 6);
}
}
else if(n.d == CONTENT_RAIL)
else if(n.getContent() == CONTENT_JUNGLEGRASS)
{
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
{
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
pa_papyrus.x0(), pa_papyrus.y1()),
video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
pa_papyrus.x1(), pa_papyrus.y1()),
video::S3DVertex(BS/2,BS/1,0, 0,0,0, c,
pa_papyrus.x1(), pa_papyrus.y0()),
video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c,
pa_papyrus.x0(), pa_papyrus.y0()),
};
if(j == 0)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(45);
}
else if(j == 1)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(-45);
}
else if(j == 2)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(135);
}
else if(j == 3)
{
for(u16 i=0; i<4; i++)
vertices[i].Pos.rotateXZBy(-135);
}
for(u16 i=0; i<4; i++)
{
vertices[i].Pos *= 1.3;
vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
}
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
collector.append(material_junglegrass, vertices, 4, indices, 6);
}
}
else if(n.getContent() == CONTENT_RAIL)
{
u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(255,l,l,l);
video::SColor c = MapBlock_LightColor(255, l);
bool is_rail_x [] = { false, false }; /* x-1, x+1 */
bool is_rail_z [] = { false, false }; /* z-1, z+1 */
@ -979,13 +1043,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
MapNode n_minus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z-1));
MapNode n_plus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z+1));
if(n_minus_x.d == CONTENT_RAIL)
if(n_minus_x.getContent() == CONTENT_RAIL)
is_rail_x[0] = true;
if(n_plus_x.d == CONTENT_RAIL)
if(n_plus_x.getContent() == CONTENT_RAIL)
is_rail_x[1] = true;
if(n_minus_z.d == CONTENT_RAIL)
if(n_minus_z.getContent() == CONTENT_RAIL)
is_rail_z[0] = true;
if(n_plus_z.d == CONTENT_RAIL)
if(n_plus_z.getContent() == CONTENT_RAIL)
is_rail_z[1] = true;
float d = (float)BS/16;

@ -31,6 +31,65 @@ void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness)
void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
void setWoodLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
content_t trans_table_19[][2] = {
{CONTENT_GRASS, 1},
{CONTENT_TREE, 4},
{CONTENT_LEAVES, 5},
{CONTENT_GRASS_FOOTSTEPS, 6},
{CONTENT_MESE, 7},
{CONTENT_MUD, 8},
{CONTENT_CLOUD, 10},
{CONTENT_COALSTONE, 11},
{CONTENT_WOOD, 12},
{CONTENT_SAND, 13},
{CONTENT_COBBLE, 18},
{CONTENT_STEEL, 19},
{CONTENT_GLASS, 20},
{CONTENT_MOSSYCOBBLE, 22},
{CONTENT_GRAVEL, 23},
{CONTENT_SANDSTONE, 24},
{CONTENT_CACTUS, 25},
{CONTENT_BRICK, 26},
{CONTENT_CLAY, 27},
{CONTENT_PAPYRUS, 28},
{CONTENT_BOOKSHELF, 29},
};
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version)
{
MapNode result = n_from;
if(version <= 19)
{
content_t c_from = n_from.getContent();
for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
{
if(trans_table_19[i][0] == c_from)
{
result.setContent(trans_table_19[i][1]);
break;
}
}
}
return result;
}
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
{
MapNode result = n_from;
if(version <= 19)
{
content_t c_from = n_from.getContent();
for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++)
{
if(trans_table_19[i][1] == c_from)
{
result.setContent(trans_table_19[i][0]);
break;
}
}
}
return result;
}
void content_mapnode_init()
{
// Read some settings
@ -38,7 +97,7 @@ void content_mapnode_init()
bool new_style_leaves = g_settings.getBool("new_style_leaves");
bool invisible_stone = g_settings.getBool("invisible_stone");
u8 i;
content_t i;
ContentFeatures *f = NULL;
i = CONTENT_STONE;
@ -136,12 +195,34 @@ void content_mapnode_init()
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
setWoodLikeDiggingProperties(f->digging_properties, 1.0);
i = CONTENT_JUNGLETREE;
f = &content_features(i);
f->setAllTextures("jungletree.png");
f->setTexture(0, "jungletree_top.png");
f->setTexture(1, "jungletree_top.png");
f->param_type = CPT_MINERAL;
//f->is_ground_content = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
setWoodLikeDiggingProperties(f->digging_properties, 1.0);
i = CONTENT_JUNGLEGRASS;
f = &content_features(i);
f->setInventoryTexture("junglegrass.png");
f->light_propagates = true;
f->param_type = CPT_LIGHT;
//f->is_ground_content = true;
f->air_equivalent = false; // grass grows underneath
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
f->solidness = 0; // drawn separately, makes no faces
f->walkable = false;
setWoodLikeDiggingProperties(f->digging_properties, 0.10);
i = CONTENT_LEAVES;
f = &content_features(i);
f->light_propagates = true;
//f->param_type = CPT_MINERAL;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
//f->is_ground_content = true;
if(new_style_leaves)
{
f->solidness = 0; // drawn separately, makes no faces
@ -191,6 +272,7 @@ void content_mapnode_init()
i = CONTENT_GLASS;
f = &content_features(i);
f->light_propagates = true;
f->sunlight_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";

@ -20,43 +20,57 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CONTENT_MAPNODE_HEADER
#define CONTENT_MAPNODE_HEADER
#include "mapnode.h"
void content_mapnode_init();
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version);
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
/*
Node content type IDs
Ranges:
*/
// 0x000...0x07f (0...127): param2 is fully usable
// 126 and 127 are reserved.
// Use these sparingly, only when the extra space in param2 might be needed.
#define CONTENT_STONE 0
#define CONTENT_GRASS 1
#define CONTENT_WATER 2
#define CONTENT_TORCH 3
#define CONTENT_TREE 4
#define CONTENT_LEAVES 5
#define CONTENT_GRASS_FOOTSTEPS 6
#define CONTENT_MESE 7
#define CONTENT_MUD 8
#define CONTENT_WATERSOURCE 9
// Pretty much useless, clouds won't be drawn this way
#define CONTENT_CLOUD 10
#define CONTENT_COALSTONE 11
#define CONTENT_WOOD 12
#define CONTENT_SAND 13
#define CONTENT_SIGN_WALL 14
#define CONTENT_CHEST 15
#define CONTENT_FURNACE 16
//#define CONTENT_WORKBENCH 17
#define CONTENT_COBBLE 18
#define CONTENT_STEEL 19
#define CONTENT_GLASS 20
#define CONTENT_FENCE 21
#define CONTENT_MOSSYCOBBLE 22
#define CONTENT_GRAVEL 23
#define CONTENT_SANDSTONE 24
#define CONTENT_CACTUS 25
#define CONTENT_BRICK 26
#define CONTENT_CLAY 27
#define CONTENT_PAPYRUS 28
#define CONTENT_BOOKSHELF 29
#define CONTENT_RAIL 30
// 0x800...0xfff (2048...4095): higher 4 bytes of param2 are not usable
#define CONTENT_GRASS 0x800 //1
#define CONTENT_TREE 0x801 //4
#define CONTENT_LEAVES 0x802 //5
#define CONTENT_GRASS_FOOTSTEPS 0x803 //6
#define CONTENT_MESE 0x804 //7
#define CONTENT_MUD 0x805 //8
// Pretty much useless, clouds won't be drawn this way
#define CONTENT_CLOUD 0x806 //10
#define CONTENT_COALSTONE 0x807 //11
#define CONTENT_WOOD 0x808 //12
#define CONTENT_SAND 0x809 //13
#define CONTENT_COBBLE 0x80a //18
#define CONTENT_STEEL 0x80b //19
#define CONTENT_GLASS 0x80c //20
#define CONTENT_MOSSYCOBBLE 0x80d //22
#define CONTENT_GRAVEL 0x80e //23
#define CONTENT_SANDSTONE 0x80f //24
#define CONTENT_CACTUS 0x810 //25
#define CONTENT_BRICK 0x811 //26
#define CONTENT_CLAY 0x812 //27
#define CONTENT_PAPYRUS 0x813 //28
#define CONTENT_BOOKSHELF 0x814 //29
#define CONTENT_JUNGLETREE 0x815
#define CONTENT_JUNGLEGRASS 0x816
#endif

@ -51,7 +51,7 @@ void set_default_settings()
g_settings.setDefault("wanted_fps", "30");
g_settings.setDefault("fps_max", "60");
g_settings.setDefault("viewing_range_nodes_max", "300");
g_settings.setDefault("viewing_range_nodes_min", "25");
g_settings.setDefault("viewing_range_nodes_min", "15");
g_settings.setDefault("screenW", "800");
g_settings.setDefault("screenH", "600");
g_settings.setDefault("address", "");

@ -543,11 +543,11 @@ void spawnRandomObjects(MapBlock *block)
{
v3s16 p(x0,y0,z0);
MapNode n = block->getNodeNoEx(p);
if(n.d == CONTENT_IGNORE)
if(n.getContent() == CONTENT_IGNORE)
continue;
if(content_features(n.d).liquid_type != LIQUID_NONE)
if(content_features(n).liquid_type != LIQUID_NONE)
continue;
if(content_features(n.d).walkable)
if(content_features(n).walkable)
{
last_node_walkable = true;
continue;
@ -555,7 +555,7 @@ void spawnRandomObjects(MapBlock *block)
if(last_node_walkable)
{
// If block contains light information
if(content_features(n.d).param_type == CPT_LIGHT)
if(content_features(n).param_type == CPT_LIGHT)
{
if(n.getLight(LIGHTBANK_DAY) <= 5)
{
@ -624,15 +624,15 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
#if 1
// Test something:
// Convert all mud under proper day lighting to grass
if(n.d == CONTENT_MUD)
if(n.getContent() == CONTENT_MUD)
{
if(dtime_s > 300)
{
MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
if(content_features(n_top.d).air_equivalent &&
if(content_features(n_top).air_equivalent &&
n_top.getLight(LIGHTBANK_DAY) >= 13)
{
n.d = CONTENT_GRASS;
n.setContent(CONTENT_GRASS);
m_map->addNodeWithEvent(p, n);
}
}
@ -686,9 +686,9 @@ void ServerEnvironment::step(float dtime)
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
try{
MapNode n = m_map->getNode(bottompos);
if(n.d == CONTENT_GRASS)
if(n.getContent() == CONTENT_GRASS)
{
n.d = CONTENT_GRASS_FOOTSTEPS;
n.setContent(CONTENT_GRASS_FOOTSTEPS);
m_map->setNode(bottompos, n);
}
}
@ -859,15 +859,15 @@ void ServerEnvironment::step(float dtime)
Test something:
Convert mud under proper lighting to grass
*/
if(n.d == CONTENT_MUD)
if(n.getContent() == CONTENT_MUD)
{
if(myrand()%20 == 0)
{
MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
if(content_features(n_top.d).air_equivalent &&
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
if(content_features(n_top).air_equivalent &&
n_top.getLightBlend(getDayNightRatio()) >= 13)
{
n.d = CONTENT_GRASS;
n.setContent(CONTENT_GRASS);
m_map->addNodeWithEvent(p, n);
}
}
@ -875,15 +875,14 @@ void ServerEnvironment::step(float dtime)
/*
Convert grass into mud if under something else than air
*/
else if(n.d == CONTENT_GRASS)
else if(n.getContent() == CONTENT_GRASS)
{
//if(myrand()%20 == 0)
{
MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
if(n_top.d != CONTENT_AIR
&& n_top.d != CONTENT_IGNORE)
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
if(content_features(n_top).air_equivalent == false)
{
n.d = CONTENT_MUD;
n.setContent(CONTENT_MUD);
m_map->addNodeWithEvent(p, n);
}
}
@ -1633,9 +1632,9 @@ void ClientEnvironment::step(float dtime)
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0), BS);
try{
MapNode n = m_map->getNode(bottompos);
if(n.d == CONTENT_GRASS)
if(n.getContent() == CONTENT_GRASS)
{
n.d = CONTENT_GRASS_FOOTSTEPS;
n.setContent(CONTENT_GRASS_FOOTSTEPS);
m_map->setNode(bottompos, n);
// Update mesh on client
if(m_map->mapType() == MAPTYPE_CLIENT)
@ -1874,7 +1873,7 @@ void ClientEnvironment::drawPostFx(video::IVideoDriver* driver, v3f camera_pos)
v3f pos_f = camera_pos;
v3s16 p_nodes = floatToInt(pos_f, BS);
MapNode n = m_map->getNodeNoEx(p_nodes);
if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
{
v2u32 ss = driver->getScreenSize();
core::rect<s32> rect(0,0, ss.X, ss.Y);

@ -417,7 +417,7 @@ void getPointedNode(Client *client, v3f player_position,
try
{
n = client->getNode(v3s16(x,y,z));
if(content_pointable(n.d) == false)
if(content_pointable(n.getContent()) == false)
continue;
}
catch(InvalidPositionException &e)
@ -442,9 +442,9 @@ void getPointedNode(Client *client, v3f player_position,
/*
Meta-objects
*/
if(n.d == CONTENT_TORCH)
if(n.getContent() == CONTENT_TORCH)
{
v3s16 dir = unpackDir(n.dir);
v3s16 dir = unpackDir(n.param2);
v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f;
@ -489,9 +489,9 @@ void getPointedNode(Client *client, v3f player_position,
}
}
}
else if(n.d == CONTENT_SIGN_WALL)
else if(n.getContent() == CONTENT_SIGN_WALL)
{
v3s16 dir = unpackDir(n.dir);
v3s16 dir = unpackDir(n.param2);
v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f;
@ -538,9 +538,9 @@ void getPointedNode(Client *client, v3f player_position,
}
}
}
else if(n.d == CONTENT_RAIL)
else if(n.getContent() == CONTENT_RAIL)
{
v3s16 dir = unpackDir(n.dir);
v3s16 dir = unpackDir(n.param0);
v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f;
@ -1038,9 +1038,9 @@ void the_game(
//bool screensize_changed = screensize != last_screensize;
// Resize hotbar
if(screensize.Y <= 600)
if(screensize.Y <= 800)
hotbar_imagesize = 32;
else if(screensize.Y <= 1024)
else if(screensize.Y <= 1280)
hotbar_imagesize = 48;
else
hotbar_imagesize = 64;
@ -1759,7 +1759,7 @@ void the_game(
}
// Get digging properties for material and tool
u8 material = n.d;
content_t material = n.getContent();
DiggingProperties prop =
getDiggingProperties(material, toolname);

@ -61,7 +61,7 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
is>>material;
u16 count;
is>>count;
if(material > 255)
if(material > MAX_CONTENT)
throw SerializationError("Too large material number");
return new MaterialItem(material, count);
}

@ -30,8 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h"
#include "debug.h"
#include "mapblockobject.h"
// For g_materials
#include "main.h"
#include "main.h" // For g_materials
#include "mapnode.h" // For content_t
#define QUANTITY_ITEM_MAX_COUNT 99
@ -113,7 +113,7 @@ protected:
class MaterialItem : public InventoryItem
{
public:
MaterialItem(u8 content, u16 count):
MaterialItem(content_t content, u16 count):
InventoryItem(count)
{
m_content = content;
@ -175,12 +175,12 @@ public:
/*
Special methods
*/
u8 getMaterial()
content_t getMaterial()
{
return m_content;
}
private:
u8 m_content;
content_t m_content;
};
//TODO: Remove

File diff suppressed because it is too large Load Diff

@ -630,9 +630,9 @@ s16 Map::propagateSunlight(v3s16 start,
else
{
/*// Turn mud into grass
if(n.d == CONTENT_MUD)
if(n.getContent() == CONTENT_MUD)
{
n.d = CONTENT_GRASS;
n.setContent(CONTENT_GRASS);
block->setNode(relpos, n);
modified_blocks.insert(blockpos, block);
}*/
@ -920,15 +920,15 @@ 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.d).walkable == true)
if(content_features(n).walkable == true)
{
try{
MapNode bottomnode = getNode(bottompos);
if(bottomnode.d == CONTENT_GRASS
|| bottomnode.d == CONTENT_GRASS_FOOTSTEPS)
if(bottomnode.getContent() == CONTENT_GRASS
|| bottomnode.getContent() == CONTENT_GRASS_FOOTSTEPS)
{
bottomnode.d = CONTENT_MUD;
bottomnode.setContent(CONTENT_MUD);
setNode(bottompos, bottomnode);
}
}
@ -943,9 +943,9 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
If the new node is mud and it is under sunlight, change it
to grass
*/
if(n.d == CONTENT_MUD && node_under_sunlight)
if(n.getContent() == CONTENT_MUD && node_under_sunlight)
{
n.d = CONTENT_GRASS;
n.setContent(CONTENT_GRASS);
}
#endif
@ -986,7 +986,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
If node lets sunlight through and is under sunlight, it has
sunlight too.
*/
if(node_under_sunlight && content_features(n.d).sunlight_propagates)
if(node_under_sunlight && content_features(n).sunlight_propagates)
{
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
}
@ -1001,7 +1001,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
Add intial metadata
*/
NodeMetadata *meta_proto = content_features(n.d).initial_metadata;
NodeMetadata *meta_proto = content_features(n).initial_metadata;
if(meta_proto)
{
NodeMetadata *meta = meta_proto->clone();
@ -1015,7 +1015,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.d).sunlight_propagates)
if(node_under_sunlight && !content_features(n).sunlight_propagates)
{
s16 y = p.Y - 1;
for(;; y--){
@ -1086,7 +1086,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
if(content_liquid(n2.d) || n2.d == CONTENT_AIR)
if(content_liquid(n2.getContent()))
{
m_transforming_liquid.push_back(p2);
}
@ -1111,7 +1111,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
v3s16 toppos = p + v3s16(0,1,0);
// Node will be replaced with this
u8 replace_material = CONTENT_AIR;
content_t replace_material = CONTENT_AIR;
/*
If there is a node at top and it doesn't have sunlight,
@ -1158,7 +1158,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
*/
MapNode n;
n.d = replace_material;
n.setContent(replace_material);
setNode(p, n);
for(s32 i=0; i<2; i++)
@ -1260,7 +1260,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
if(content_liquid(n2.d) || n2.d == CONTENT_AIR)
if(content_liquid(n2.getContent()))
{
m_transforming_liquid.push_back(p2);
}
@ -1576,20 +1576,20 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
*/
s8 liquid_level = -1;
u8 liquid_kind = CONTENT_IGNORE;
LiquidType liquid_type = content_features(n0.d).liquid_type;
LiquidType liquid_type = content_features(n0.getContent()).liquid_type;
switch (liquid_type) {
case LIQUID_SOURCE:
liquid_level = 8;
liquid_kind = content_features(n0.d).liquid_alternative_flowing;
liquid_kind = content_features(n0.getContent()).liquid_alternative_flowing;
break;
case LIQUID_FLOWING:
liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
liquid_kind = n0.d;
liquid_kind = n0.getContent();
break;
case LIQUID_NONE:
// if this is an air node, it *could* be transformed into a liquid. otherwise,
// continue with the next node.
if (n0.d != CONTENT_AIR)
if (n0.getContent() != CONTENT_AIR)
continue;
liquid_kind = CONTENT_AIR;
break;
@ -1627,9 +1627,9 @@ 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.d).liquid_type) {
switch (content_features(nb.n.getContent()).liquid_type) {
case LIQUID_NONE:
if (nb.n.d == CONTENT_AIR) {
if (nb.n.getContent() == CONTENT_AIR) {
airs[num_airs++] = nb;
// if the current node happens to be a flowing node, it will start to flow down here.
if (nb.t == NEIGHBOR_LOWER)
@ -1641,8 +1641,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.d).liquid_alternative_flowing;
if (content_features(nb.n.d).liquid_alternative_flowing !=liquid_kind) {
liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
sources[num_sources++] = nb;
@ -1651,8 +1651,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.d).liquid_alternative_flowing;
if (content_features(nb.n.d).liquid_alternative_flowing != liquid_kind) {
liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
flows[num_flows++] = nb;
@ -1722,7 +1722,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.d && (content_features(n0.d).liquid_type != LIQUID_FLOWING ||
if (new_node_content == n0.getContent() && (content_features(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)))
@ -1733,8 +1733,8 @@ 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));
n0.d = new_node_content;
if (content_features(n0.d).liquid_type == LIQUID_FLOWING) {
n0.setContent(new_node_content);
if (content_features(n0.getContent()).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 {
@ -1749,7 +1749,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
/*
enqueue neighbors for update if neccessary
*/
switch (content_features(n0.d).liquid_type) {
switch (content_features(n0.getContent()).liquid_type) {
case LIQUID_SOURCE:
// make sure source flows into all neighboring nodes
for (u16 i = 0; i < num_flows; i++)
@ -2003,8 +2003,10 @@ ServerMap::~ServerMap()
void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
{
/*dstream<<"initBlockMake(): ("<<blockpos.X<<","<<blockpos.Y<<","
<<blockpos.Z<<")"<<std::endl;*/
bool enable_mapgen_debug_info = g_settings.getBool("enable_mapgen_debug_info");
if(enable_mapgen_debug_info)
dstream<<"initBlockMake(): ("<<blockpos.X<<","<<blockpos.Y<<","
<<blockpos.Z<<")"<<std::endl;
// Do nothing if not inside limits (+-1 because of neighbors)
if(blockpos_over_limit(blockpos - v3s16(1,1,1)) ||
@ -2034,25 +2036,28 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
for(s16 y=-1; y<=1; y++)
{
//MapBlock *block = createBlock(blockpos);
v3s16 p(blockpos.X+x, blockpos.Y+y, blockpos.Z+z);
//MapBlock *block = createBlock(p);
// 1) get from memory, 2) load from disk
MapBlock *block = emergeBlock(blockpos, false);
MapBlock *block = emergeBlock(p, false);
// 3) create a blank one
if(block == NULL)
block = createBlock(blockpos);
{
block = createBlock(p);
/*
Block gets sunlight if this is true.
Refer to the map generator heuristics.
*/
bool ug = mapgen::block_is_underground(data->seed, p);
block->setIsUnderground(ug);
}
// Lighting will not be valid after make_chunk is called
block->setLightingExpired(true);
// Lighting will be calculated
//block->setLightingExpired(false);
/*
Block gets sunlight if this is true.
This should be set to true when the top side of a block
is completely exposed to the sky.
*/
block->setIsUnderground(false);
}
}
}
@ -2128,10 +2133,14 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
assert(block);
/*
Set is_underground flag for lighting with sunlight
*/
Set is_underground flag for lighting with sunlight.
Refer to map generator heuristics.
NOTE: This is done in initChunkMake
*/
//block->setIsUnderground(mapgen::block_is_underground(data->seed, blockpos));
block->setIsUnderground(mapgen::block_is_underground(data->seed, blockpos));
/*
Add sunlight to central block.
@ -2162,6 +2171,13 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
#if 1
// Center block
lighting_update_blocks.insert(block->getPos(), block);
/*{
s16 x = 0;
s16 z = 0;
v3s16 p = block->getPos()+v3s16(x,1,z);
lighting_update_blocks[p] = getBlockNoCreateNoEx(p);
}*/
#endif
#if 0
// All modified blocks
@ -2178,8 +2194,28 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
lighting_update_blocks.insert(i.getNode()->getKey(),
i.getNode()->getValue());
}
/*// Also force-add all the upmost blocks for proper sunlight
for(s16 x=-1; x<=1; x++)
for(s16 z=-1; z<=1; z++)
{
v3s16 p = block->getPos()+v3s16(x,1,z);
lighting_update_blocks[p] = getBlockNoCreateNoEx(p);
}*/
#endif
updateLighting(lighting_update_blocks, changed_blocks);
/*
Set lighting to non-expired state in all of them.
This is cheating, but it is not fast enough if all of them
would actually be updated.
*/
for(s16 x=-1; x<=1; x++)
for(s16 y=-1; y<=1; y++)
for(s16 z=-1; z<=1; z++)
{
v3s16 p = block->getPos()+v3s16(x,y,z);
getBlockNoCreateNoEx(p)->setLightingExpired(false);
}
if(enable_mapgen_debug_info == false)
t.stop(true); // Hide output
@ -2221,7 +2257,26 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
/*dstream<<"finishBlockMake() done for ("<<blockpos.X<<","<<blockpos.Y<<","
<<blockpos.Z<<")"<<std::endl;*/
#if 0
if(enable_mapgen_debug_info)
{
/*
Analyze resulting blocks
*/
for(s16 x=-1; x<=1; x++)
for(s16 y=-1; y<=1; y++)
for(s16 z=-1; z<=1; z++)
{
v3s16 p = block->getPos()+v3s16(x,y,z);
MapBlock *block = getBlockNoCreateNoEx(p);
char spos[20];
snprintf(spos, 20, "(%2d,%2d,%2d)", x, y, z);
dstream<<"Generated "<<spos<<": "
<<analyze_block(block)<<std::endl;
}
}
#endif
return block;
}
@ -2355,7 +2410,7 @@ MapBlock * ServerMap::generateBlock(
{
v3s16 p(x0,y0,z0);
MapNode n = block->getNode(p);
if(n.d == CONTENT_IGNORE)
if(n.getContent() == CONTENT_IGNORE)
{
dstream<<"CONTENT_IGNORE at "
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@ -2384,9 +2439,9 @@ MapBlock * ServerMap::generateBlock(
{
MapNode n;
if(y0%2==0)
n.d = CONTENT_AIR;
n.setContent(CONTENT_AIR);
else
n.d = CONTENT_STONE;
n.setContent(CONTENT_STONE);
block->setNode(v3s16(x0,y0,z0), n);
}
}
@ -2470,7 +2525,7 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool allow_generate)
{
MapBlock *block = getBlockNoCreateNoEx(p);
if(block)
if(block && block->isDummy() == false)
return block;
}
@ -2667,19 +2722,19 @@ s16 ServerMap::findGroundLevel(v2s16 p2d)
for(; p.Y>min; p.Y--)
{
MapNode n = getNodeNoEx(p);
if(n.d != CONTENT_IGNORE)
if(n.getContent() != CONTENT_IGNORE)
break;
}
if(p.Y == min)
goto plan_b;
// If this node is not air, go to plan b
if(getNodeNoEx(p).d != CONTENT_AIR)
if(getNodeNoEx(p).getContent() != CONTENT_AIR)
goto plan_b;
// Search existing walkable and return it
for(; p.Y>min; p.Y--)
{
MapNode n = getNodeNoEx(p);
if(content_walkable(n.d) && n.d != CONTENT_IGNORE)
if(content_walkable(n.d) && n.getContent() != CONTENT_IGNORE)
return p.Y;
}
@ -4072,10 +4127,16 @@ void ManualMapVoxelManipulator::blitBackAll(
i = m_loaded_blocks.getIterator();
i.atEnd() == false; i++)
{
v3s16 p = i.getNode()->getKey();
bool existed = i.getNode()->getValue();
if(existed == false)
{
// The Great Bug was found using this
/*dstream<<"ManualMapVoxelManipulator::blitBackAll: "
<<"Inexistent ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<std::endl;*/
continue;
v3s16 p = i.getNode()->getKey();
}
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if(block == NULL)
{

@ -242,7 +242,12 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
// Check if node above block has sunlight
try{
MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
if(n.d == CONTENT_IGNORE || n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
if(n.getContent() == CONTENT_IGNORE)
{
// Trust heuristics
no_sunlight = is_underground;
}
else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
{
no_sunlight = true;
}
@ -260,8 +265,8 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
else
{
MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
//if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
if(content_features(n.d).sunlight_propagates == false)
//if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
if(content_features(n).sunlight_propagates == false)
{
no_sunlight = true;
}
@ -322,14 +327,14 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
bool upper_is_air = false;
try
{
if(getNodeParent(pos+v3s16(0,1,0)).d == CONTENT_AIR)
if(getNodeParent(pos+v3s16(0,1,0)).getContent() == CONTENT_AIR)
upper_is_air = true;
}
catch(InvalidPositionException &e)
{
}
// Turn mud into grass
if(upper_is_air && n.d == CONTENT_MUD
if(upper_is_air && n.getContent() == CONTENT_MUD
&& current_light == LIGHT_SUN)
{
n.d = CONTENT_GRASS;
@ -473,7 +478,7 @@ void MapBlock::updateDayNightDiff()
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
{
MapNode &n = data[i];
if(n.d != CONTENT_AIR)
if(n.getContent() != CONTENT_AIR)
{
only_air = false;
break;
@ -496,8 +501,8 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
s16 y = MAP_BLOCKSIZE-1;
for(; y>=0; y--)
{
//if(is_ground_content(getNodeRef(p2d.X, y, p2d.Y).d))
if(content_features(getNodeRef(p2d.X, y, p2d.Y).d).walkable)
MapNode n = getNodeRef(p2d.X, y, p2d.Y);
if(content_features(n).walkable)
{
if(y == MAP_BLOCKSIZE-1)
return -2;
@ -560,7 +565,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
SharedBuffer<u8> materialdata(nodecount);
for(u32 i=0; i<nodecount; i++)
{
materialdata[i] = data[i].d;
materialdata[i] = data[i].param0;
}
compress(materialdata, os, version);
@ -568,7 +573,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
SharedBuffer<u8> lightdata(nodecount);
for(u32 i=0; i<nodecount; i++)
{
lightdata[i] = data[i].param;
lightdata[i] = data[i].param1;
}
compress(lightdata, os, version);
@ -715,7 +720,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
("MapBlock::deSerialize: invalid format");
for(u32 i=0; i<s.size(); i++)
{
data[i].d = s[i];
data[i].param0 = s[i];
}
}
{
@ -728,7 +733,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
("MapBlock::deSerialize: invalid format");
for(u32 i=0; i<s.size(); i++)
{
data[i].param = s[i];
data[i].param1 = s[i];
}
}
@ -862,5 +867,130 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
}
}
/*
Get a quick string to describe what a block actually contains
*/
std::string analyze_block(MapBlock *block)
{
if(block == NULL)
{
return "NULL";
}
std::ostringstream desc;
v3s16 p = block->getPos();
char spos[20];
snprintf(spos, 20, "(%2d,%2d,%2d), ", p.X, p.Y, p.Z);
desc<<spos;
switch(block->getModified())
{
case MOD_STATE_CLEAN:
desc<<"CLEAN, ";
break;
case MOD_STATE_WRITE_AT_UNLOAD:
desc<<"WRITE_AT_UNLOAD, ";
break;
case MOD_STATE_WRITE_NEEDED:
desc<<"WRITE_NEEDED, ";
break;
default:
desc<<"unknown getModified()="+itos(block->getModified())+", ";
}
if(block->isGenerated())
desc<<"is_gen [X], ";
else
desc<<"is_gen [ ], ";
if(block->getIsUnderground())
desc<<"is_ug [X], ";
else
desc<<"is_ug [ ], ";
#ifndef SERVER
if(block->getMeshExpired())
desc<<"mesh_exp [X], ";
else
desc<<"mesh_exp [ ], ";
#endif
if(block->getLightingExpired())
desc<<"lighting_exp [X], ";
else
desc<<"lighting_exp [ ], ";
if(block->isDummy())
{
desc<<"Dummy, ";
}
else
{
// We'll just define the numbers here, don't want to include
// content_mapnode.h
const content_t content_water = 2;
const content_t content_watersource = 9;
const content_t content_tree = 0x801;
const content_t content_leaves = 0x802;
const content_t content_jungletree = 0x815;
bool full_ignore = true;
bool some_ignore = false;
bool full_air = true;
bool some_air = false;
bool trees = false;
bool water = false;
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
{
v3s16 p(x0,y0,z0);
MapNode n = block->getNode(p);
content_t c = n.getContent();
if(c == CONTENT_IGNORE)
some_ignore = true;
else
full_ignore = false;
if(c == CONTENT_AIR)
some_air = true;
else
full_air = false;
if(c == content_tree || c == content_jungletree
|| c == content_leaves)
trees = true;
if(c == content_water
|| c == content_watersource)
water = true;
}
desc<<"content {";
std::ostringstream ss;
if(full_ignore)
ss<<"IGNORE (full), ";
else if(some_ignore)
ss<<"IGNORE, ";
if(full_air)
ss<<"AIR (full), ";
else if(some_air)
ss<<"AIR, ";
if(trees)
ss<<"trees, ";
if(water)
ss<<"water, ";
if(ss.str().size()>=2)
desc<<ss.str().substr(0, ss.str().size()-2);
desc<<"}, ";
}
return desc.str().substr(0, desc.str().size()-2);
}
//END

@ -743,5 +743,10 @@ inline s16 getNodeBlockY(s16 y)
return getContainerPos(y, MAP_BLOCKSIZE);
}
/*
Get a quick string to describe what a block actually contains
*/
std::string analyze_block(MapBlock *block);
#endif

@ -140,9 +140,24 @@ void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
}
}
inline video::SColor lightColor(u8 alpha, u8 light)
video::SColor MapBlock_LightColor(u8 alpha, u8 light)
{
#if 0
return video::SColor(alpha,light,light,light);
#endif
//return video::SColor(alpha,light,light,MYMAX(0, (s16)light-25)+25);
/*return video::SColor(alpha,light,light,MYMAX(0,
pow((float)light/255.0, 0.8)*255.0));*/
#if 1
// Emphase blue a bit in darker places
float lim = 80;
float power = 0.8;
if(light > lim)
return video::SColor(alpha,light,light,light);
else
return video::SColor(alpha,light,light,MYMAX(0,
pow((float)light/lim, power)*lim));
#endif
}
struct FastFace
@ -198,7 +213,7 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
float w = tile.texture.size.X;
float h = tile.texture.size.Y;
/*video::SColor c = lightColor(alpha, li);
/*video::SColor c = MapBlock_LightColor(alpha, li);
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0), c,
core::vector2d<f32>(x0+w*abs_scale, y0+h));
@ -210,16 +225,16 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
core::vector2d<f32>(x0+w*abs_scale, y0));*/
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0),
lightColor(alpha, li0),
MapBlock_LightColor(alpha, li0),
core::vector2d<f32>(x0+w*abs_scale, y0+h));
face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0),
lightColor(alpha, li1),
MapBlock_LightColor(alpha, li1),
core::vector2d<f32>(x0, y0+h));
face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0),
lightColor(alpha, li2),
MapBlock_LightColor(alpha, li2),
core::vector2d<f32>(x0, y0));
face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0),
lightColor(alpha, li3),
MapBlock_LightColor(alpha, li3),
core::vector2d<f32>(x0+w*abs_scale, y0));
face.tile = tile;
@ -285,7 +300,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
return spec;
}
u8 getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
content_t getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
{
/*
Check temporary modifications on this node
@ -320,7 +335,7 @@ u8 getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
}
}
return mn.d;
return mn.getContent();
}
v3s16 dirs8[8] = {
@ -343,16 +358,16 @@ 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.d).param_type == CPT_LIGHT
if(content_features(n).param_type == CPT_LIGHT
// Fast-style leaves look better this way
&& content_features(n.d).solidness != 2)
&& content_features(n).solidness != 2)
{
light += decode_light(n.getLightBlend(daynight_ratio));
light_count++;
}
else
{
if(n.d != CONTENT_IGNORE)
if(n.getContent() != CONTENT_IGNORE)
ambient_occlusion++;
}
}
@ -408,8 +423,8 @@ void getTileInfo(
TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
// This is hackish
u8 content0 = getNodeContent(p, n0, temp_mods);
u8 content1 = getNodeContent(p + face_dir, n1, temp_mods);
content_t content0 = getNodeContent(p, n0, temp_mods);
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
u8 mf = face_contents(content0, content1);
if(mf == 0)

@ -121,6 +121,9 @@ private:
core::array<PreMeshBuffer> m_prebuffers;
};
// Helper functions
video::SColor MapBlock_LightColor(u8 alpha, u8 light);
class MapBlock;
struct MeshMakeData
@ -137,6 +140,7 @@ struct MeshMakeData
void fill(u32 daynight_ratio, MapBlock *block);
};
// This is the highest-level function in here
scene::SMesh* makeMapBlockMesh(MeshMakeData *data);
#endif

@ -161,8 +161,8 @@ void MovingObject::move(float dtime, v3f acceleration)
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
{
try{
if(content_walkable(m_block->getNodeParent(v3s16(x,y,z)).d)
== false)
MapNode n = m_block->getNodeParent(v3s16(x,y,z));
if(content_features(n).walkable == false)
continue;
}
catch(InvalidPositionException &e)

@ -67,8 +67,8 @@ static s16 find_ground_level_clever(VoxelManipulator &vmanip, v2s16 p2d)
{
MapNode &n = vmanip.m_data[i];
if(content_walkable(n.d)
&& n.d != CONTENT_TREE
&& n.d != CONTENT_LEAVES)
&& n.getContent() != CONTENT_TREE
&& n.getContent() != CONTENT_LEAVES)
break;
vmanip.m_area.add_y(em, i, -1);
@ -143,8 +143,94 @@ static void make_tree(VoxelManipulator &vmanip, v3s16 p0)
if(vmanip.m_area.contains(p) == false)
continue;
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d != CONTENT_AIR
&& vmanip.m_data[vi].d != CONTENT_IGNORE)
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;
u32 i = leaves_a.index(x,y,z);
if(leaves_d[i] == 1)
vmanip.m_data[vi] = leavesnode;
}
}
static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0)
{
MapNode treenode(CONTENT_JUNGLETREE);
MapNode leavesnode(CONTENT_LEAVES);
for(s16 x=-1; x<=1; x++)
for(s16 z=-1; z<=1; z++)
{
if(myrand_range(0, 2) == 0)
continue;
v3s16 p1 = p0 + v3s16(x,0,z);
v3s16 p2 = p0 + v3s16(x,-1,z);
if(vmanip.m_area.contains(p2)
&& vmanip.m_data[vmanip.m_area.index(p2)] == CONTENT_AIR)
vmanip.m_data[vmanip.m_area.index(p2)] = treenode;
else if(vmanip.m_area.contains(p1))
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
}
s16 trunk_h = myrand_range(8, 12);
v3s16 p1 = p0;
for(s16 ii=0; ii<trunk_h; ii++)
{
if(vmanip.m_area.contains(p1))
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
p1.Y++;
}
// p1 is now the last piece of the trunk
p1.Y -= 1;
VoxelArea leaves_a(v3s16(-3,-2,-3), v3s16(3,2,3));
//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;
// Force leaves at near the end of the trunk
{
s16 d = 1;
for(s16 z=-d; z<=d; z++)
for(s16 y=-d; y<=d; y++)
for(s16 x=-d; x<=d; x++)
{
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
}
}
// Add leaves randomly
for(u32 iii=0; iii<30; iii++)
{
s16 d = 1;
v3s16 p(
myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
);
for(s16 z=0; z<=d; z++)
for(s16 y=0; y<=d; y++)
for(s16 x=0; x<=d; x++)
{
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
}
}
// Blit leaves to vmanip
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
{
v3s16 p(x,y,z);
p += p1;
if(vmanip.m_area.contains(p) == false)
continue;
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;
u32 i = leaves_a.index(x,y,z);
if(leaves_d[i] == 1)
@ -251,8 +337,8 @@ static void make_randomstone(VoxelManipulator &vmanip, v3s16 p0)
if(vmanip.m_area.contains(p) == false)
continue;
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d != CONTENT_AIR
&& vmanip.m_data[vi].d != CONTENT_IGNORE)
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;
u32 i = stone_a.index(x,y,z);
if(stone_d[i] == 1)
@ -335,8 +421,8 @@ static void make_largestone(VoxelManipulator &vmanip, v3s16 p0)
if(vmanip.m_area.contains(p) == false)
continue;
u32 vi = vmanip.m_area.index(p);
/*if(vmanip.m_data[vi].d != CONTENT_AIR
&& vmanip.m_data[vi].d != CONTENT_IGNORE)
/*if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;*/
u32 i = stone_a.index(x,y,z);
if(stone_d[i] == 1)
@ -544,9 +630,9 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace,
p.Y += make_stairs;
/*// If already empty
if(vmanip.getNodeNoExNoEmerge(p).d
if(vmanip.getNodeNoExNoEmerge(p).getContent()
== CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
== CONTENT_AIR)
{
}*/
@ -642,9 +728,9 @@ public:
randomizeDir();
continue;
}
if(vmanip.getNodeNoExNoEmerge(p).d
if(vmanip.getNodeNoExNoEmerge(p).getContent()
== CONTENT_COBBLE
&& vmanip.getNodeNoExNoEmerge(p1).d
&& vmanip.getNodeNoExNoEmerge(p1).getContent()
== CONTENT_COBBLE)
{
// Found wall, this is a good place!
@ -658,25 +744,25 @@ public:
Determine where to move next
*/
// Jump one up if the actual space is there
if(vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).d
if(vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).getContent()
== CONTENT_COBBLE
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
== CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,2,0)).d
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,2,0)).getContent()
== CONTENT_AIR)
p += v3s16(0,1,0);
// Jump one down if the actual space is there
if(vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d
if(vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
== CONTENT_COBBLE
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).d
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).getContent()
== CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,-1,0)).d
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,-1,0)).getContent()
== CONTENT_AIR)
p += v3s16(0,-1,0);
// Check if walking is now possible
if(vmanip.getNodeNoExNoEmerge(p).d
if(vmanip.getNodeNoExNoEmerge(p).getContent()
!= CONTENT_AIR
|| vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d
|| vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
!= CONTENT_AIR)
{
// Cannot continue walking here
@ -798,7 +884,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random)
fits = false;
break;
}
if(vmanip.m_data[vi].d == CONTENT_IGNORE)
if(vmanip.m_data[vi].getContent() == CONTENT_IGNORE)
{
fits = false;
break;
@ -1004,13 +1090,26 @@ double tree_amount_2d(u64 seed, v2s16 p)
double noise = noise2d_perlin(
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
seed+2, 4, 0.66);
double zeroval = -0.35;
double zeroval = -0.39;
if(noise < zeroval)
return 0;
else
return 0.04 * (noise-zeroval) / (1.0-zeroval);
}
double surface_humidity_2d(u64 seed, v2s16 p)
{
double noise = noise2d_perlin(
0.5+(float)p.X/500, 0.5+(float)p.Y/500,
seed+72384, 4, 0.66);
noise = (noise + 1.0)/2.0;
if(noise < 0.0)
noise = 0.0;
if(noise > 1.0)
noise = 1.0;
return noise;
}
#if 0
double randomstone_amount_2d(u64 seed, v2s16 p)
{
@ -1273,11 +1372,11 @@ void add_random_objects(MapBlock *block)
{
v3s16 p(x0,y0,z0);
MapNode n = block->getNodeNoEx(p);
if(n.d == CONTENT_IGNORE)
if(n.getContent() == CONTENT_IGNORE)
continue;
if(content_features(n.d).liquid_type != LIQUID_NONE)
if(content_features(n).liquid_type != LIQUID_NONE)
continue;
if(content_features(n.d).walkable)
if(content_features(n).walkable)
{
last_node_walkable = true;
continue;
@ -1285,7 +1384,7 @@ void add_random_objects(MapBlock *block)
if(last_node_walkable)
{
// If block contains light information
if(content_features(n.d).param_type == CPT_LIGHT)
if(content_features(n).param_type == CPT_LIGHT)
{
if(n.getLight(LIGHTBANK_DAY) <= 3)
{
@ -1392,7 +1491,7 @@ void make_block(BlockMakeData *data)
for(s16 y=node_min.Y; y<=node_max.Y; y++)
{
// Only modify places that have no content
if(vmanip.m_data[i].d == CONTENT_IGNORE)
if(vmanip.m_data[i].getContent() == CONTENT_IGNORE)
{
if(y <= WATER_LEVEL)
vmanip.m_data[i] = MapNode(CONTENT_WATERSOURCE);
@ -1498,7 +1597,7 @@ void make_block(BlockMakeData *data)
for(s16 y=node_min.Y; y<=node_max.Y; y++)
{
// Only modify places that have no content
if(vmanip.m_data[i].d == CONTENT_IGNORE)
if(vmanip.m_data[i].getContent() == CONTENT_IGNORE)
{
// First priority: make air and water.
// This avoids caves inside water.
@ -1543,7 +1642,7 @@ void make_block(BlockMakeData *data)
{
v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d == CONTENT_STONE)
if(vmanip.m_data[vi].getContent() == CONTENT_STONE)
if(mineralrandom.next()%8 == 0)
vmanip.m_data[vi] = MapNode(CONTENT_MESE);
}
@ -1584,13 +1683,13 @@ void make_block(BlockMakeData *data)
{
}*/
if(new_content.d != CONTENT_IGNORE)
if(new_content.getContent() != CONTENT_IGNORE)
{
for(u16 i=0; i<27; i++)
{
v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d == base_content)
if(vmanip.m_data[vi].getContent() == base_content)
{
if(mineralrandom.next()%sparseness == 0)
vmanip.m_data[vi] = new_content;
@ -1621,7 +1720,7 @@ void make_block(BlockMakeData *data)
{
v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d == CONTENT_STONE)
if(vmanip.m_data[vi].getContent() == CONTENT_STONE)
if(mineralrandom.next()%8 == 0)
vmanip.m_data[vi] = MapNode(CONTENT_STONE, MINERAL_COAL);
}
@ -1647,7 +1746,7 @@ void make_block(BlockMakeData *data)
{
v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d == CONTENT_STONE)
if(vmanip.m_data[vi].getContent() == CONTENT_STONE)
if(mineralrandom.next()%8 == 0)
vmanip.m_data[vi] = MapNode(CONTENT_STONE, MINERAL_IRON);
}
@ -1670,7 +1769,7 @@ void make_block(BlockMakeData *data)
u32 i = vmanip.m_area.index(v3s16(p2d.X, node_max.Y, p2d.Y));
for(s16 y=node_max.Y; y>=node_min.Y; y--)
{
if(vmanip.m_data[i].d == CONTENT_STONE)
if(vmanip.m_data[i].getContent() == CONTENT_STONE)
{
if(noisebuf_ground_crumbleness.get(x,y,z) > 1.3)
{
@ -1722,9 +1821,9 @@ void make_block(BlockMakeData *data)
u32 i = vmanip.m_area.index(v3s16(p2d.X, full_node_max.Y, p2d.Y));
for(s16 y=full_node_max.Y; y>=full_node_min.Y; y--)
{
if(vmanip.m_data[i].d == CONTENT_AIR)
if(vmanip.m_data[i].getContent() == CONTENT_AIR)
vmanip.m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
else if(vmanip.m_data[i].d == CONTENT_WATERSOURCE)
else if(vmanip.m_data[i].getContent() == CONTENT_WATERSOURCE)
vmanip.m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
data->vmanip->m_area.add_y(em, i, -1);
}
@ -1755,17 +1854,17 @@ void make_block(BlockMakeData *data)
double d = noise3d_perlin((float)x/2.5,
(float)y/2.5,(float)z/2.5,
blockseed, 2, 1.4);
if(vmanip.m_data[i].d == CONTENT_COBBLE)
if(vmanip.m_data[i].getContent() == CONTENT_COBBLE)
{
if(d < wetness/3.0)
{
vmanip.m_data[i].d = CONTENT_MOSSYCOBBLE;
vmanip.m_data[i].setContent(CONTENT_MOSSYCOBBLE);
}
}
/*else if(vmanip.m_flags[i] & VMANIP_FLAG_DUNGEON_INSIDE)
{
if(wetness > 1.2)
vmanip.m_data[i].d = CONTENT_MUD;
vmanip.m_data[i].setContent(CONTENT_MUD);
}*/
data->vmanip->m_area.add_y(em, i, -1);
}
@ -1791,7 +1890,7 @@ void make_block(BlockMakeData *data)
{
if(water_found == false)
{
if(vmanip.m_data[i].d == CONTENT_WATERSOURCE)
if(vmanip.m_data[i].getContent() == CONTENT_WATERSOURCE)
{
v3s16 p = v3s16(p2d.X, y, p2d.Y);
data->transforming_liquid.push_back(p);
@ -1803,7 +1902,7 @@ void make_block(BlockMakeData *data)
// This can be done because water_found can only
// turn to true and end up here after going through
// a single block.
if(vmanip.m_data[i+1].d != CONTENT_WATERSOURCE)
if(vmanip.m_data[i+1].getContent() != CONTENT_WATERSOURCE)
{
v3s16 p = v3s16(p2d.X, y+1, p2d.Y);
data->transforming_liquid.push_back(p);
@ -1846,16 +1945,16 @@ void make_block(BlockMakeData *data)
u32 i = vmanip.m_area.index(v3s16(p2d.X, start_y, p2d.Y));
for(s16 y=start_y; y>=node_min.Y-3; y--)
{
if(vmanip.m_data[i].d == CONTENT_WATERSOURCE)
if(vmanip.m_data[i].getContent() == CONTENT_WATERSOURCE)
water_detected = true;
if(vmanip.m_data[i].d == CONTENT_AIR)
if(vmanip.m_data[i].getContent() == CONTENT_AIR)
air_detected = true;
if((vmanip.m_data[i].d == CONTENT_STONE
|| vmanip.m_data[i].d == CONTENT_GRASS
|| vmanip.m_data[i].d == CONTENT_MUD
|| vmanip.m_data[i].d == CONTENT_SAND
|| vmanip.m_data[i].d == CONTENT_GRAVEL
if((vmanip.m_data[i].getContent() == CONTENT_STONE
|| vmanip.m_data[i].getContent() == CONTENT_GRASS
|| vmanip.m_data[i].getContent() == CONTENT_MUD
|| vmanip.m_data[i].getContent() == CONTENT_SAND
|| vmanip.m_data[i].getContent() == CONTENT_GRAVEL
) && (air_detected || water_detected))
{
if(current_depth == 0 && y <= WATER_LEVEL+2
@ -1890,8 +1989,8 @@ void make_block(BlockMakeData *data)
}
else
{
if(vmanip.m_data[i].d == CONTENT_MUD
|| vmanip.m_data[i].d == CONTENT_GRASS)
if(vmanip.m_data[i].getContent() == CONTENT_MUD
|| vmanip.m_data[i].getContent() == CONTENT_GRASS)
vmanip.m_data[i] = MapNode(CONTENT_STONE);
}
@ -1909,11 +2008,19 @@ void make_block(BlockMakeData *data)
}
/*
Add trees
Calculate some stuff
*/
float surface_humidity = surface_humidity_2d(data->seed, p2d_center);
bool is_jungle = surface_humidity > 0.75;
// Amount of trees
u32 tree_count = block_area_nodes * tree_amount_2d(data->seed, p2d_center);
if(is_jungle)
tree_count *= 5;
/*
Add trees
*/
PseudoRandom treerandom(blockseed);
// Put trees in random places on part of division
for(u32 i=0; i<tree_count; i++)
@ -1938,7 +2045,7 @@ void make_block(BlockMakeData *data)
{
u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i];
if(n->d != CONTENT_AIR && n->d != CONTENT_WATERSOURCE && n->d != CONTENT_IGNORE)
if(n->getContent() != CONTENT_AIR && n->getContent() != CONTENT_WATERSOURCE && n->getContent() != CONTENT_IGNORE)
{
found = true;
break;
@ -1952,23 +2059,27 @@ void make_block(BlockMakeData *data)
u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i];
if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS && n->d != CONTENT_SAND)
if(n->getContent() != CONTENT_MUD && n->getContent() != CONTENT_GRASS && n->getContent() != CONTENT_SAND)
continue;
// Papyrus grows only on mud and in water
if(n->d == CONTENT_MUD && y <= WATER_LEVEL)
if(n->getContent() == CONTENT_MUD && y <= WATER_LEVEL)
{
p.Y++;
make_papyrus(vmanip, p);
}
// Trees grow only on mud and grass, on land
else if((n->d == CONTENT_MUD || n->d == CONTENT_GRASS) && y > WATER_LEVEL + 2)
else if((n->getContent() == CONTENT_MUD || n->getContent() == CONTENT_GRASS) && y > WATER_LEVEL + 2)
{
p.Y++;
make_tree(vmanip, p);
//if(surface_humidity_2d(data->seed, v2s16(x, y)) < 0.5)
if(is_jungle == false)
make_tree(vmanip, p);
else
make_jungletree(vmanip, p);
}
// Cactii grow only on sand, on land
else if(n->d == CONTENT_SAND && y > WATER_LEVEL + 2)
else if(n->getContent() == CONTENT_SAND && y > WATER_LEVEL + 2)
{
p.Y++;
make_cactus(vmanip, p);
@ -1976,6 +2087,54 @@ void make_block(BlockMakeData *data)
}
}
/*
Add jungle grass
*/
if(is_jungle)
{
PseudoRandom grassrandom(blockseed);
for(u32 i=0; i<surface_humidity*5*tree_count; i++)
{
s16 x = grassrandom.range(node_min.X, node_max.X);
s16 z = grassrandom.range(node_min.Z, node_max.Z);
s16 y = find_ground_level_from_noise(data->seed, v2s16(x,z), 4);
if(y < WATER_LEVEL)
continue;
if(y < node_min.Y || y > node_max.Y)
continue;
/*
Find exact ground level
*/
v3s16 p(x,y+6,z);
bool found = false;
for(; p.Y >= y-6; p.Y--)
{
u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i];
if(content_features(*n).is_ground_content
|| n->getContent() == CONTENT_JUNGLETREE)
{
found = true;
break;
}
}
// If not found, handle next one
if(found == false)
continue;
p.Y++;
if(vmanip.m_area.contains(p) == false)
continue;
if(vmanip.m_data[vmanip.m_area.index(p)].getContent() != CONTENT_AIR)
continue;
/*p.Y--;
if(vmanip.m_area.contains(p))
vmanip.m_data[vmanip.m_area.index(p)] = CONTENT_MUD;
p.Y++;*/
if(vmanip.m_area.contains(p))
vmanip.m_data[vmanip.m_area.index(p)] = CONTENT_JUNGLEGRASS;
}
}
#if 0
/*
Add some kind of random stones
@ -2000,7 +2159,7 @@ void make_block(BlockMakeData *data)
/*{
u32 i = data->vmanip->m_area.index(v3s16(p));
MapNode *n = &data->vmanip->m_data[i];
if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
if(n->getContent() != CONTENT_MUD && n->getContent() != CONTENT_GRASS)
continue;
}*/
// Will be placed one higher
@ -2035,7 +2194,7 @@ void make_block(BlockMakeData *data)
/*{
u32 i = data->vmanip->m_area.index(v3s16(p));
MapNode *n = &data->vmanip->m_data[i];
if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
if(n->getContent() != CONTENT_MUD && n->getContent() != CONTENT_GRASS)
continue;
}*/
// Will be placed one lower

@ -30,8 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
ContentFeatures::~ContentFeatures()
{
/*if(translate_to)
delete translate_to;*/
if(initial_metadata)
delete initial_metadata;
}
@ -83,12 +81,16 @@ void ContentFeatures::setInventoryTextureCube(std::string top,
inventory_texture = g_texturesource->getTextureRaw(imgname_full);
}
struct ContentFeatures g_content_features[256];
struct ContentFeatures g_content_features[MAX_CONTENT+1];
ContentFeatures & content_features(u8 i)
ContentFeatures & content_features(content_t i)
{
return g_content_features[i];
}
ContentFeatures & content_features(MapNode &n)
{
return content_features(n.getContent());
}
/*
See mapnode.h for description.
@ -128,7 +130,7 @@ void init_mapnode()
initial_material_type = MATERIAL_ALPHA_SIMPLE;
else
initial_material_type = MATERIAL_ALPHA_NONE;*/
for(u16 i=0; i<256; i++)
for(u16 i=0; i<MAX_CONTENT+1; i++)
{
ContentFeatures *f = &g_content_features[i];
// Re-initialize
@ -142,7 +144,7 @@ void init_mapnode()
Initially set every block to be shown as an unknown block.
Don't touch CONTENT_IGNORE or CONTENT_AIR.
*/
for(u16 i=0; i<256; i++)
for(u16 i=0; i<MAX_CONTENT+1; i++)
{
if(i == CONTENT_IGNORE || i == CONTENT_AIR)
continue;
@ -183,7 +185,7 @@ v3s16 facedir_rotate(u8 facedir, v3s16 dir)
TileSpec MapNode::getTile(v3s16 dir)
{
if(content_features(d).param_type == CPT_FACEDIR_SIMPLE)
if(content_features(*this).param_type == CPT_FACEDIR_SIMPLE)
dir = facedir_rotate(param1, dir);
TileSpec spec;
@ -207,16 +209,16 @@ TileSpec MapNode::getTile(v3s16 dir)
if(dir_i == -1)
// Non-directional
spec = content_features(d).tiles[0];
spec = content_features(*this).tiles[0];
else
spec = content_features(d).tiles[dir_i];
spec = content_features(*this).tiles[dir_i];
/*
If it contains some mineral, change texture id
*/
if(content_features(d).param_type == CPT_MINERAL && g_texturesource)
if(content_features(*this).param_type == CPT_MINERAL && g_texturesource)
{
u8 mineral = param & 0x1f;
u8 mineral = getMineral();
std::string mineral_texture_name = mineral_block_texture(mineral);
if(mineral_texture_name != "")
{
@ -235,9 +237,9 @@ TileSpec MapNode::getTile(v3s16 dir)
u8 MapNode::getMineral()
{
if(content_features(d).param_type == CPT_MINERAL)
if(content_features(*this).param_type == CPT_MINERAL)
{
return param & 0x1f;
return param1 & 0x0f;
}
return MINERAL_NONE;
@ -260,33 +262,36 @@ void MapNode::serialize(u8 *dest, u8 version)
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported");
u8 actual_d = d;
// Translate to wanted version
MapNode n_foreign = mapnode_translate_from_internal(*this, version);
// Convert from new version to old
u8 actual_param0 = n_foreign.param0;
// Convert special values from new version to old
if(version <= 18)
{
// In these versions, CONTENT_IGNORE and CONTENT_AIR
// are 255 and 254
if(actual_d == CONTENT_IGNORE)
actual_d = 255;
else if(actual_d == CONTENT_AIR)
actual_d = 254;
if(actual_param0 == CONTENT_IGNORE)
actual_param0 = 255;
else if(actual_param0 == CONTENT_AIR)
actual_param0 = 254;
}
if(version == 0)
{
dest[0] = actual_d;
dest[0] = actual_param0;
}
else if(version <= 9)
{
dest[0] = actual_d;
dest[1] = param;
dest[0] = actual_param0;
dest[1] = n_foreign.param1;
}
else
{
dest[0] = actual_d;
dest[1] = param;
dest[2] = param2;
dest[0] = actual_param0;
dest[1] = n_foreign.param1;
dest[2] = n_foreign.param2;
}
}
void MapNode::deSerialize(u8 *source, u8 version)
@ -296,47 +301,50 @@ void MapNode::deSerialize(u8 *source, u8 version)
if(version == 0)
{
d = source[0];
param0 = source[0];
}
else if(version == 1)
{
d = source[0];
param0 = source[0];
// This version doesn't support saved lighting
if(light_propagates() || light_source() > 0)
param = 0;
param1 = 0;
else
param = source[1];
param1 = source[1];
}
else if(version <= 9)
{
d = source[0];
param = source[1];
param0 = source[0];
param1 = source[1];
}
else
{
d = source[0];
param = source[1];
param0 = source[0];
param1 = source[1];
param2 = source[2];
}
// Convert from old version to new
// Convert special values from old version to new
if(version <= 18)
{
// In these versions, CONTENT_IGNORE and CONTENT_AIR
// are 255 and 254
if(d == 255)
d = CONTENT_IGNORE;
else if(d == 254)
d = CONTENT_AIR;
if(param0 == 255)
param0 = CONTENT_IGNORE;
else if(param0 == 254)
param0 = CONTENT_AIR;
}
// version 19 is fucked up with sometimes the old values and sometimes not
if(version == 19)
{
if(d == 255)
d = CONTENT_IGNORE;
else if(d == 254)
d = CONTENT_AIR;
if(param0 == 255)
param0 = CONTENT_IGNORE;
else if(param0 == 254)
param0 = CONTENT_AIR;
}
// Translate to our known version
*this = mapnode_translate_to_internal(*this, version);
}
/*

@ -32,16 +32,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/*
Naming scheme:
- Material = irrlicht's Material class
- Content = (u8) content of a node
- Content = (content_t) content of a node
- Tile = TileSpec at some side of a node of some content type
*/
/*
Ranges:
Content ranges:
0x000...0x07f: param2 is fully usable
0x800...0xfff: param2 lower 4 bytes are free
*/
typedef u16 content_t;
#define MAX_CONTENT 0xfff
/*
Initializes all kind of stuff in here.
@ -102,10 +101,7 @@ class NodeMetadata;
struct ContentFeatures
{
// If non-NULL, content is translated to this when deserialized
//MapNode *translate_to;
// Type of MapNode::param
// Type of MapNode::param1
ContentParamType param_type;
/*
@ -119,7 +115,8 @@ struct ContentFeatures
TileSpec tiles[6];
video::ITexture *inventory_texture;
// True for all ground-like things like stone and mud, false for eg. trees
bool is_ground_content;
bool light_propagates;
bool sunlight_propagates;
@ -150,10 +147,10 @@ struct ContentFeatures
NodeMetadata *initial_metadata;
// If the content is liquid, this is the flowing version of the liquid.
// If content is flowing liquid, this is the same content.
u8 liquid_alternative_flowing;
// If content is liquid, this is the same content.
content_t liquid_alternative_flowing;
// If the content is liquid, this is the source version of the liquid.
u8 liquid_alternative_source;
content_t liquid_alternative_source;
// Amount of light the node emits
u8 light_source;
@ -165,7 +162,6 @@ struct ContentFeatures
void reset()
{
//translate_to = NULL;
param_type = CPT_NONE;
inventory_texture = NULL;
is_ground_content = false;
@ -230,8 +226,8 @@ struct ContentFeatures
/*
Call this to access the ContentFeature list
*/
ContentFeatures & content_features(u8 i);
ContentFeatures & content_features(content_t i);
ContentFeatures & content_features(MapNode &n);
/*
Here is a bunch of DEPRECATED functions.
@ -242,7 +238,7 @@ ContentFeatures & content_features(u8 i);
in param.
NOTE: Don't use, use "content_features(m).whatever" instead
*/
inline bool light_propagates_content(u8 m)
inline bool light_propagates_content(content_t m)
{
return content_features(m).light_propagates;
}
@ -251,7 +247,7 @@ inline bool light_propagates_content(u8 m)
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(u8 m)
inline bool sunlight_propagates_content(content_t m)
{
return content_features(m).sunlight_propagates;
}
@ -263,35 +259,35 @@ inline bool sunlight_propagates_content(u8 m)
2: Opaque
NOTE: Don't use, use "content_features(m).whatever" instead
*/
inline u8 content_solidness(u8 m)
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(u8 m)
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(u8 m)
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(u8 m)
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(u8 m)
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 u8 make_liquid_flowing(u8 m)
inline content_t make_liquid_flowing(content_t m)
{
u8 c = content_features(m).liquid_alternative_flowing;
assert(c != CONTENT_IGNORE);
@ -299,17 +295,17 @@ inline u8 make_liquid_flowing(u8 m)
}
// Pointable contents can be pointed to in the map
// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_pointable(u8 m)
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(u8 m)
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(u8 m)
inline bool content_buildable_to(content_t m)
{
return content_features(m).buildable_to;
}
@ -321,7 +317,7 @@ inline bool content_buildable_to(u8 m)
1: Face uses m1's content
2: Face uses m2's content
*/
inline u8 face_contents(u8 m1, u8 m2)
inline u8 face_contents(content_t m1, content_t m2)
{
if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
return 0;
@ -425,7 +421,7 @@ struct MapNode
union
{
u8 param0;
u8 d;
//u8 d;
};
/*
@ -440,17 +436,18 @@ struct MapNode
union
{
u8 param1;
s8 param;
//s8 param;
};
/*
The second parameter. Initialized to 0.
E.g. direction for torches and flowing water.
If param0 >= 0x80, bits 0xf0 of this is extended content type data
*/
union
{
u8 param2;
u8 dir;
//u8 dir;
};
MapNode(const MapNode & n)
@ -458,28 +455,44 @@ struct MapNode
*this = n;
}
MapNode(u8 data=CONTENT_AIR, u8 a_param=0, u8 a_param2=0)
MapNode(content_t content=CONTENT_AIR, u8 a_param1=0, u8 a_param2=0)
{
d = data;
param = a_param;
//param0 = a_param0;
param1 = a_param1;
param2 = a_param2;
// Set after other params because this needs to override part of param2
setContent(content);
}
bool operator==(const MapNode &other)
{
return (d == other.d
&& param == other.param
return (param0 == other.param0
&& param1 == other.param1
&& param2 == other.param2);
}
// To be used everywhere
content_t getContent()
{
return d;
if(param0 < 0x80)
return param0;
else
return (param0<<4) + (param2>>4);
}
void setContent(content_t c)
{
d = c;
if(c < 0x80)
{
if(param0 >= 0x80)
param2 &= ~(0xf0);
param0 = c;
}
else
{
param0 = c>>4;
param2 &= ~(0xf0);
param2 |= (c&0x0f)<<4;
}
}
/*
@ -487,19 +500,19 @@ struct MapNode
*/
bool light_propagates()
{
return light_propagates_content(d);
return light_propagates_content(getContent());
}
bool sunlight_propagates()
{
return sunlight_propagates_content(d);
return sunlight_propagates_content(getContent());
}
u8 solidness()
{
return content_solidness(d);
return content_solidness(getContent());
}
u8 light_source()
{
return content_features(d).light_source;
return content_features(*this).light_source;
}
u8 getLightBanksWithSource()
@ -507,10 +520,10 @@ struct MapNode
// Select the brightest of [light source, propagated light]
u8 lightday = 0;
u8 lightnight = 0;
if(content_features(d).param_type == CPT_LIGHT)
if(content_features(*this).param_type == CPT_LIGHT)
{
lightday = param & 0x0f;
lightnight = (param>>4)&0x0f;
lightday = param1 & 0x0f;
lightnight = (param1>>4)&0x0f;
}
if(light_source() > lightday)
lightday = light_source();
@ -523,12 +536,12 @@ struct MapNode
{
// Select the brightest of [light source, propagated light]
u8 light = 0;
if(content_features(d).param_type == CPT_LIGHT)
if(content_features(*this).param_type == CPT_LIGHT)
{
if(bank == LIGHTBANK_DAY)
light = param & 0x0f;
light = param1 & 0x0f;
else if(bank == LIGHTBANK_NIGHT)
light = (param>>4)&0x0f;
light = (param1>>4)&0x0f;
else
assert(0);
}
@ -566,17 +579,17 @@ struct MapNode
void setLight(enum LightBank bank, u8 a_light)
{
// If node doesn't contain light data, ignore this
if(content_features(d).param_type != CPT_LIGHT)
if(content_features(*this).param_type != CPT_LIGHT)
return;
if(bank == LIGHTBANK_DAY)
{
param &= 0xf0;
param |= a_light & 0x0f;
param1 &= 0xf0;
param1 |= a_light & 0x0f;
}
else if(bank == LIGHTBANK_NIGHT)
{
param &= 0x0f;
param |= (a_light & 0x0f)<<4;
param1 &= 0x0f;
param1 |= (a_light & 0x0f)<<4;
}
else
assert(0);

@ -3,12 +3,12 @@
// NOTE: DEPRECATED
DiggingPropertiesList * getDiggingPropertiesList(u8 content)
DiggingPropertiesList * getDiggingPropertiesList(u16 content)
{
return &content_features(content).digging_properties;
}
DiggingProperties getDiggingProperties(u8 content, const std::string &tool)
DiggingProperties getDiggingProperties(u16 content, const std::string &tool)
{
DiggingPropertiesList *mprop = getDiggingPropertiesList(content);
if(mprop == NULL)

@ -97,7 +97,7 @@ private:
};
// For getting the default properties, set tool=""
DiggingProperties getDiggingProperties(u8 material, const std::string &tool);
DiggingProperties getDiggingProperties(u16 material, const std::string &tool);
#endif

@ -342,13 +342,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).d);
in_water = content_liquid(map.getNode(pp).getContent());
}
// 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).d);
in_water = content_liquid(map.getNode(pp).getContent());
}
}
catch(InvalidPositionException &e)
@ -361,7 +361,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).d);
in_water_stable = content_liquid(map.getNode(pp).getContent());
}
catch(InvalidPositionException &e)
{
@ -470,7 +470,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
{
try{
// Player collides into walkable nodes
if(content_walkable(map.getNode(v3s16(x,y,z)).d) == false)
if(content_walkable(map.getNode(v3s16(x,y,z)).getContent()) == false)
continue;
}
catch(InvalidPositionException &e)
@ -633,10 +633,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).d) == false)
if(content_walkable(map.getNode(p).getContent()) == false)
continue;
// And the node above it has to be nonwalkable
if(content_walkable(map.getNode(p+v3s16(0,1,0)).d) == true)
if(content_walkable(map.getNode(p+v3s16(0,1,0)).getContent()) == true)
continue;
}
catch(InvalidPositionException &e)

@ -55,11 +55,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
17: MapBlocks contain timestamp
18: new generator (not really necessary, but it's there)
19: new content type handling
20: many existing content types translated to extended ones
*/
// This represents an uninitialized or invalid format
#define SER_FMT_VER_INVALID 255
// Highest supported serialization version
#define SER_FMT_VER_HIGHEST 19
#define SER_FMT_VER_HIGHEST 20
// Lowest supported serialization version
#define SER_FMT_VER_LOWEST 0

@ -105,10 +105,10 @@ void * EmergeThread::Thread()
DSTACK(__FUNCTION_NAME);
//bool debug=false;
BEGIN_DEBUG_EXCEPTION_HANDLER
bool enable_mapgen_debug_info = g_settings.getBool("enable_mapgen_debug_info");
/*
Get block info from queue, emerge them and send them
to clients.
@ -155,7 +155,7 @@ void * EmergeThread::Thread()
Also decrement the emerge queue count in clients.
*/
bool optional = true;
bool only_from_disk = true;
{
core::map<u16, u8>::Iterator i;
@ -166,14 +166,15 @@ void * EmergeThread::Thread()
// Check flags
u8 flags = i.getNode()->getValue();
if((flags & BLOCK_EMERGE_FLAG_FROMDISK) == false)
optional = false;
only_from_disk = false;
}
}
/*dstream<<"EmergeThread: p="
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
<<"optional="<<optional<<std::endl;*/
if(enable_mapgen_debug_info)
dstream<<"EmergeThread: p="
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
<<"only_from_disk="<<only_from_disk<<std::endl;
ServerMap &map = ((ServerMap&)m_server->m_env.getMap());
@ -184,11 +185,6 @@ void * EmergeThread::Thread()
bool got_block = true;
core::map<v3s16, MapBlock*> modified_blocks;
bool only_from_disk = false;
if(optional)
only_from_disk = true;
/*
Fetch block from map or generate a single block
*/
@ -203,6 +199,9 @@ void * EmergeThread::Thread()
block = map.getBlockNoCreateNoEx(p);
if(!block || block->isDummy() || !block->isGenerated())
{
if(enable_mapgen_debug_info)
dstream<<"EmergeThread: not in memory, loading"<<std::endl;
// Get, load or create sector
/*ServerMapSector *sector =
(ServerMapSector*)map.createSector(p2d);*/
@ -213,12 +212,20 @@ void * EmergeThread::Thread()
lighting_invalidated_blocks);*/
block = map.loadBlock(p);
if(only_from_disk == false)
{
if(block == NULL || block->isGenerated() == false)
{
if(enable_mapgen_debug_info)
dstream<<"EmergeThread: generating"<<std::endl;
block = map.generateBlock(p, modified_blocks);
}
}
if(block == NULL && only_from_disk == false)
block = map.generateBlock(p, modified_blocks);
//block = map.generateBlock(p, changed_blocks);
/*block = map.generateBlock(p, block, sector, changed_blocks,
lighting_invalidated_blocks);*/
if(enable_mapgen_debug_info)
dstream<<"EmergeThread: ended up with: "
<<analyze_block(block)<<std::endl;
if(block == NULL)
{
@ -2494,7 +2501,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Mandatory parameter; actually used for nothing
core::map<v3s16, MapBlock*> modified_blocks;
u8 material = CONTENT_IGNORE;
content_t material = CONTENT_IGNORE;
u8 mineral = MINERAL_NONE;
bool cannot_remove_node = false;
@ -2505,7 +2512,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Get mineral
mineral = n.getMineral();
// Get material at position
material = n.d;
material = n.getContent();
// If not yet cancelled
if(cannot_remove_node == false)
{
@ -2705,7 +2712,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" because privileges are "<<getPlayerPrivs(player)
<<std::endl;
if(content_buildable_to(n2.d) == false
if(content_features(n2).buildable_to == false
|| no_enough_privs)
{
// Client probably has wrong data.
@ -2736,14 +2743,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Create node data
MaterialItem *mitem = (MaterialItem*)item;
MapNode n;
n.d = mitem->getMaterial();
n.setContent(mitem->getMaterial());
// Calculate direction for wall mounted stuff
if(content_features(n.d).wall_mounted)
n.dir = packDir(p_under - p_over);
if(content_features(n).wall_mounted)
n.param2 = packDir(p_under - p_over);
// Calculate the direction for furnaces and chests and stuff
if(content_features(n.d).param_type == CPT_FACEDIR_SIMPLE)
if(content_features(n).param_type == CPT_FACEDIR_SIMPLE)
{
v3f playerpos = player->getPosition();
v3f blockpos = intToFloat(p_over, BS) - playerpos;

@ -219,14 +219,14 @@ struct TestMapNode
MapNode n;
// Default values
assert(n.d == CONTENT_AIR);
assert(n.getContent() == CONTENT_AIR);
assert(n.getLight(LIGHTBANK_DAY) == 0);
assert(n.getLight(LIGHTBANK_NIGHT) == 0);
// Transparency
n.d = CONTENT_AIR;
n.setContent(CONTENT_AIR);
assert(n.light_propagates() == true);
n.d = CONTENT_STONE;
n.setContent(CONTENT_STONE);
assert(n.light_propagates() == false);
}
};
@ -284,7 +284,7 @@ struct TestVoxelManipulator
v.print(dstream);
assert(v.getNode(v3s16(-1,0,-1)).d == 2);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
dstream<<"*** Reading from inexistent (0,0,-1) ***"<<std::endl;
@ -298,7 +298,7 @@ struct TestVoxelManipulator
v.print(dstream);
assert(v.getNode(v3s16(-1,0,-1)).d == 2);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
#if 0
@ -331,11 +331,11 @@ struct TestVoxelManipulator
MapNode n;
//n.pressure = size.Y - y;
if(*p == '#')
n.d = CONTENT_STONE;
n.setContent(CONTENT_STONE);
else if(*p == '.')
n.d = CONTENT_WATER;
n.setContent(CONTENT_WATER);
else if(*p == ' ')
n.d = CONTENT_AIR;
n.setContent(CONTENT_AIR);
else
assert(0);
v.setNode(v3s16(x,y,z), n);
@ -469,8 +469,8 @@ struct TestMapBlock
for(u16 y=0; y<MAP_BLOCKSIZE; y++)
for(u16 x=0; x<MAP_BLOCKSIZE; x++)
{
//assert(b.getNode(v3s16(x,y,z)).d == CONTENT_AIR);
assert(b.getNode(v3s16(x,y,z)).d == CONTENT_IGNORE);
//assert(b.getNode(v3s16(x,y,z)).getContent() == CONTENT_AIR);
assert(b.getNode(v3s16(x,y,z)).getContent() == CONTENT_IGNORE);
assert(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_NIGHT) == 0);
}
@ -489,7 +489,7 @@ struct TestMapBlock
Parent fetch functions
*/
parent.position_valid = false;
parent.node.d = 5;
parent.node.setContent(5);
MapNode n;
@ -497,7 +497,7 @@ struct TestMapBlock
assert(b.isValidPositionParent(v3s16(0,0,0)) == true);
assert(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true);
n = b.getNodeParent(v3s16(0,MAP_BLOCKSIZE-1,0));
assert(n.d == CONTENT_AIR);
assert(n.getContent() == CONTENT_AIR);
// ...but outside the block they should be invalid
assert(b.isValidPositionParent(v3s16(-121,2341,0)) == false);
@ -523,15 +523,15 @@ struct TestMapBlock
assert(b.isValidPositionParent(v3s16(-1,0,0)) == true);
assert(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE)) == true);
n = b.getNodeParent(v3s16(0,0,MAP_BLOCKSIZE));
assert(n.d == 5);
assert(n.getContent() == 5);
/*
Set a node
*/
v3s16 p(1,2,0);
n.d = 4;
n.setContent(4);
b.setNode(p, n);
assert(b.getNode(p).d == 4);
assert(b.getNode(p).getContent() == 4);
//TODO: Update to new system
/*assert(b.getNodeTile(p) == 4);
assert(b.getNodeTile(v3s16(-1,-1,0)) == 5);*/
@ -556,7 +556,7 @@ struct TestMapBlock
*/
parent.position_valid = true;
b.setIsUnderground(false);
parent.node.d = CONTENT_AIR;
parent.node.setContent(CONTENT_AIR);
parent.node.setLight(LIGHTBANK_DAY, LIGHT_SUN);
parent.node.setLight(LIGHTBANK_NIGHT, 0);
core::map<v3s16, bool> light_sources;
@ -611,7 +611,7 @@ struct TestMapBlock
for(u16 y=0; y<MAP_BLOCKSIZE; y++){
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
MapNode n;
n.d = CONTENT_AIR;
n.setContent(CONTENT_AIR);
n.setLight(LIGHTBANK_DAY, 0);
b.setNode(v3s16(x,y,z), n);
}

@ -179,7 +179,7 @@ void TextureSource::processQueue()
dstream<<"INFO: TextureSource::processQueue(): "
<<"got texture request with "
<<"name="<<request.key
<<"name=\""<<request.key<<"\""
<<std::endl;
GetResult<std::string, u32, u8, u8>
@ -194,7 +194,7 @@ void TextureSource::processQueue()
u32 TextureSource::getTextureId(const std::string &name)
{
//dstream<<"INFO: getTextureId(): name="<<name<<std::endl;
//dstream<<"INFO: getTextureId(): \""<<name<<"\""<<std::endl;
{
/*
@ -218,7 +218,7 @@ u32 TextureSource::getTextureId(const std::string &name)
}
else
{
dstream<<"INFO: getTextureId(): Queued: name="<<name<<std::endl;
dstream<<"INFO: getTextureId(): Queued: name=\""<<name<<"\""<<std::endl;
// We're gonna ask the result to be put into here
ResultQueue<std::string, u32, u8, u8> result_queue;
@ -226,8 +226,8 @@ u32 TextureSource::getTextureId(const std::string &name)
// Throw a request in
m_get_texture_queue.add(name, 0, 0, &result_queue);
dstream<<"INFO: Waiting for texture from main thread, name="
<<name<<std::endl;
dstream<<"INFO: Waiting for texture from main thread, name=\""
<<name<<"\""<<std::endl;
try
{
@ -276,7 +276,7 @@ video::IImage* generate_image_from_scratch(std::string name,
*/
u32 TextureSource::getTextureIdDirect(const std::string &name)
{
dstream<<"INFO: getTextureIdDirect(): name="<<name<<std::endl;
//dstream<<"INFO: getTextureIdDirect(): name=\""<<name<<"\""<<std::endl;
// Empty name means texture 0
if(name == "")
@ -305,14 +305,14 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
n = m_name_to_id.find(name);
if(n != NULL)
{
dstream<<"INFO: getTextureIdDirect(): name="<<name
<<" found in cache"<<std::endl;
dstream<<"INFO: getTextureIdDirect(): \""<<name
<<"\" found in cache"<<std::endl;
return n->getValue();
}
}
dstream<<"INFO: getTextureIdDirect(): name="<<name
<<" NOT found in cache. Creating it."<<std::endl;
dstream<<"INFO: getTextureIdDirect(): \""<<name
<<"\" NOT found in cache. Creating it."<<std::endl;
/*
Get the base image
@ -346,12 +346,13 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
{
// Construct base name
base_image_name = name.substr(0, last_separator_position);
dstream<<"INFO: getTextureIdDirect(): Calling itself recursively"
" to get base image, name="<<base_image_name<<std::endl;
/*dstream<<"INFO: getTextureIdDirect(): Calling itself recursively"
" to get base image of \""<<name<<"\" = \""
<<base_image_name<<"\""<<std::endl;*/
base_image_id = getTextureIdDirect(base_image_name);
}
dstream<<"base_image_id="<<base_image_id<<std::endl;
//dstream<<"base_image_id="<<base_image_id<<std::endl;
video::IVideoDriver* driver = m_device->getVideoDriver();
assert(driver);
@ -393,9 +394,9 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
core::rect<s32>(pos_from, dim) // from
);
dstream<<"INFO: getTextureIdDirect(): Loaded \""
/*dstream<<"INFO: getTextureIdDirect(): Loaded \""
<<base_image_name<<"\" from image cache"
<<std::endl;
<<std::endl;*/
}
}
@ -405,7 +406,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
*/
std::string last_part_of_name = name.substr(last_separator_position+1);
dstream<<"last_part_of_name="<<last_part_of_name<<std::endl;
//dstream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;
// Generate image according to part of name
if(generate_image(last_part_of_name, baseimg, m_device) == false)
@ -447,8 +448,8 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
m_atlaspointer_cache.push_back(nap);
m_name_to_id.insert(name, id);
dstream<<"INFO: getTextureIdDirect(): name="<<name
<<": succesfully returning id="<<id<<std::endl;
/*dstream<<"INFO: getTextureIdDirect(): "
<<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl;*/
return id;
}
@ -517,13 +518,11 @@ void TextureSource::buildMainAtlas()
sourcelist.push_back("cobble.png");
sourcelist.push_back("mossycobble.png");
sourcelist.push_back("gravel.png");
sourcelist.push_back("cactus.png");
sourcelist.push_back("jungletree.png");
sourcelist.push_back("stone.png^mineral_coal.png");
sourcelist.push_back("stone.png^mineral_iron.png");
sourcelist.push_back("mud.png^mineral_coal.png");
sourcelist.push_back("mud.png^mineral_iron.png");
sourcelist.push_back("sand.png^mineral_coal.png");
sourcelist.push_back("sand.png^mineral_iron.png");
// Padding to disallow texture bleeding
s32 padding = 16;
@ -580,6 +579,9 @@ void TextureSource::buildMainAtlas()
break;
}
dstream<<"INFO: TextureSource::buildMainAtlas(): Adding \""<<name
<<"\" to texture atlas"<<std::endl;
// Tile it a few times in the X direction
u16 xwise_tiling = 16;
for(u32 j=0; j<xwise_tiling; j++)
@ -670,8 +672,8 @@ void TextureSource::buildMainAtlas()
video::IImage* generate_image_from_scratch(std::string name,
IrrlichtDevice *device)
{
dstream<<"INFO: generate_image_from_scratch(): "
"name="<<name<<std::endl;
/*dstream<<"INFO: generate_image_from_scratch(): "
"\""<<name<<"\""<<std::endl;*/
video::IVideoDriver* driver = device->getVideoDriver();
assert(driver);
@ -708,8 +710,9 @@ video::IImage* generate_image_from_scratch(std::string name,
{
// Construct base name
base_image_name = name.substr(0, last_separator_position);
dstream<<"INFO: generate_image_from_scratch(): Calling itself recursively"
" to get base image, name="<<base_image_name<<std::endl;
/*dstream<<"INFO: generate_image_from_scratch(): Calling itself recursively"
" to get base image of \""<<name<<"\" = \""
<<base_image_name<<"\""<<std::endl;*/
baseimg = generate_image_from_scratch(base_image_name, device);
}
@ -719,7 +722,7 @@ video::IImage* generate_image_from_scratch(std::string name,
*/
std::string last_part_of_name = name.substr(last_separator_position+1);
dstream<<"last_part_of_name="<<last_part_of_name<<std::endl;
//dstream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;
// Generate image according to part of name
if(generate_image(last_part_of_name, baseimg, device) == false)
@ -744,21 +747,21 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
{
// A normal texture; load it from a file
std::string path = getTexturePath(part_of_name.c_str());
dstream<<"INFO: getTextureIdDirect(): Loading path \""<<path
<<"\""<<std::endl;
/*dstream<<"INFO: generate_image(): Loading path \""<<path
<<"\""<<std::endl;*/
video::IImage *image = driver->createImageFromFile(path.c_str());
if(image == NULL)
{
dstream<<"WARNING: Could not load image \""<<part_of_name
<<"\" from path \""<<path<<"\""
dstream<<"WARNING: generate_image(): Could not load image \""
<<part_of_name<<"\" from path \""<<path<<"\""
<<" while building texture"<<std::endl;
//return false;
dstream<<"WARNING: Creating a dummy"<<" image for \""
<<part_of_name<<"\""<<std::endl;
dstream<<"WARNING: generate_image(): Creating a dummy"
<<" image for \""<<part_of_name<<"\""<<std::endl;
// Just create a dummy image
//core::dimension2d<u32> dim(2,2);
@ -782,7 +785,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
// If base image is NULL, load as base.
if(baseimg == NULL)
{
dstream<<"INFO: Setting "<<part_of_name<<" as base"<<std::endl;
//dstream<<"INFO: Setting "<<part_of_name<<" as base"<<std::endl;
/*
Copy it this way to get an alpha channel.
Otherwise images with alpha cannot be blitted on
@ -796,7 +799,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
// Else blit on base.
else
{
dstream<<"INFO: Blitting "<<part_of_name<<" on base"<<std::endl;
//dstream<<"INFO: Blitting "<<part_of_name<<" on base"<<std::endl;
// Size of the copied area
core::dimension2d<u32> dim = image->getDimension();
//core::dimension2d<u32> dim(16,16);
@ -817,7 +820,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
{
// A special texture modification
dstream<<"INFO: getTextureIdDirect(): generating special "
dstream<<"INFO: generate_image(): generating special "
<<"modification \""<<part_of_name<<"\""
<<std::endl;
@ -840,9 +843,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
{
if(baseimg == NULL)
{
dstream<<"WARNING: getTextureIdDirect(): baseimg==NULL "
<<"for part_of_name="<<part_of_name
<<", cancelling."<<std::endl;
dstream<<"WARNING: generate_image(): baseimg==NULL "
<<"for part_of_name=\""<<part_of_name
<<"\", cancelling."<<std::endl;
return false;
}
@ -977,9 +980,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
{
if(baseimg == NULL)
{
dstream<<"WARNING: getTextureIdDirect(): baseimg==NULL "
<<"for part_of_name="<<part_of_name
<<", cancelling."<<std::endl;
dstream<<"WARNING: generate_image(): baseimg==NULL "
<<"for part_of_name=\""<<part_of_name
<<"\", cancelling."<<std::endl;
return false;
}
@ -997,9 +1000,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
{
if(baseimg != NULL)
{
dstream<<"WARNING: getTextureIdDirect(): baseimg!=NULL "
<<"for part_of_name="<<part_of_name
<<", cancelling."<<std::endl;
dstream<<"WARNING: generate_image(): baseimg!=NULL "
<<"for part_of_name=\""<<part_of_name
<<"\", cancelling."<<std::endl;
return false;
}
@ -1007,14 +1010,14 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
std::string path = getTexturePath(filename.c_str());
dstream<<"INFO: getTextureIdDirect(): Loading path \""<<path
dstream<<"INFO: generate_image(): Loading path \""<<path
<<"\""<<std::endl;
video::IImage *image = driver->createImageFromFile(path.c_str());
if(image == NULL)
{
dstream<<"WARNING: getTextureIdDirect(): Loading path \""
dstream<<"WARNING: generate_image(): Loading path \""
<<path<<"\" failed"<<std::endl;
}
else
@ -1048,9 +1051,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
{
if(baseimg != NULL)
{
dstream<<"WARNING: getTextureIdDirect(): baseimg!=NULL "
<<"for part_of_name="<<part_of_name
<<", cancelling."<<std::endl;
dstream<<"WARNING: generate_image(): baseimg!=NULL "
<<"for part_of_name=\""<<part_of_name
<<"\", cancelling."<<std::endl;
return false;
}
@ -1066,7 +1069,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
if(driver->queryFeature(video::EVDF_RENDER_TO_TARGET) == false)
{
dstream<<"WARNING: getTextureIdDirect(): EVDF_RENDER_TO_TARGET"
dstream<<"WARNING: generate_image(): EVDF_RENDER_TO_TARGET"
" not supported. Creating fallback image"<<std::endl;
baseimg = generate_image_from_scratch(
imagename_top, device);
@ -1075,7 +1078,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
u32 w0 = 64;
u32 h0 = 64;
dstream<<"INFO: inventorycube w="<<w0<<" h="<<h0<<std::endl;
//dstream<<"INFO: inventorycube w="<<w0<<" h="<<h0<<std::endl;
core::dimension2d<u32> dim(w0,h0);
// Generate images for the faces of the cube
@ -1177,7 +1180,7 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
}
else
{
dstream<<"WARNING: getTextureIdDirect(): Invalid "
dstream<<"WARNING: generate_image(): Invalid "
" modification: \""<<part_of_name<<"\""<<std::endl;
}
}

@ -93,7 +93,7 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
else
{
c = 'X';
u8 m = m_data[m_area.index(x,y,z)].d;
content_t m = m_data[m_area.index(x,y,z)].getContent();
u8 pr = m_data[m_area.index(x,y,z)].param2;
if(mode == VOXELPRINT_MATERIAL)
{

@ -170,6 +170,9 @@ stuff = {}
starttime = time.time()
def data_is_air(d):
return (d == 254 or d == 126)
# Go through all sectors.
for n in range(len(xlist)):
#if n > 500:
@ -283,7 +286,7 @@ for n in range(len(xlist)):
for (x, z) in reversed(pixellist):
for y in reversed(range(16)):
datapos = x + y * 16 + z * 256
if(ord(mapdata[datapos]) != 254 and ord(mapdata[datapos]) in colors):
if(not data_is_air(ord(mapdata[datapos])) and ord(mapdata[datapos]) in colors):
if(ord(mapdata[datapos]) == 2 or ord(mapdata[datapos]) == 9):
water[(x, z)] += 1
# Add dummy stuff for drawing sea without seabed
@ -293,7 +296,7 @@ for n in range(len(xlist)):
# Memorize information on the type and height of the block and for drawing the picture.
stuff[(chunkxpos + x, chunkzpos + z)] = (chunkypos + y, ord(mapdata[datapos]), water[(x, z)])
break
elif(ord(mapdata[datapos]) != 254 and ord(mapdata[datapos]) not in colors):
elif(not data_is_air(ord(mapdata[datapos])) and ord(mapdata[datapos]) not in colors):
print "strange block: " + xhex + "/" + zhex + "/" + yhex + " x: " + str(x) + " y: " + str(y) + " z: " + str(z) + " palikka: " + str(ord(mapdata[datapos]))
# After finding all the pixels in the sector, we can move on to the next sector without having to continue the Y axis.
@ -324,7 +327,7 @@ for n in range(len(xlist)):
for (x, z) in reversed(pixellist):
for y in reversed(range(16)):
datapos = x + y * 16 + z * 256
if(ord(mapdata[datapos]) != 254 and ord(mapdata[datapos]) in colors):
if(not data_is_air(ord(mapdata[datapos])) and ord(mapdata[datapos]) in colors):
if(ord(mapdata[datapos]) == 2 or ord(mapdata[datapos]) == 9):
water[(x, z)] += 1
# Add dummy stuff for drawing sea without seabed
@ -334,7 +337,7 @@ for n in range(len(xlist)):
# Memorize information on the type and height of the block and for drawing the picture.
stuff[(chunkxpos + x, chunkzpos + z)] = (chunkypos + y, ord(mapdata[datapos]), water[(x, z)])
break
elif(ord(mapdata[datapos]) != 254 and ord(mapdata[datapos]) not in colors):
elif(not data_is_air(ord(mapdata[datapos])) and ord(mapdata[datapos]) not in colors):
print "outo palikka: " + xhex + "/" + zhex + "/" + yhex + " x: " + str(x) + " y: " + str(y) + " z: " + str(z) + " palikka: " + str(ord(mapdata[datapos]))
# After finding all the pixels in the sector, we can move on to the next sector without having to continue the Y axis.