extended content-type range

This commit is contained in:
Perttu Ahola 2011-07-23 16:55:26 +03:00
parent f706644a50
commit 90d793f8f3
27 changed files with 428 additions and 318 deletions

@ -78,7 +78,8 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
{ {
try{ try{
// Object collides into walkable nodes // 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; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)

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

@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
//#include "serverobject.h" //#include "serverobject.h"
#include "content_sao.h" #include "content_sao.h"
bool item_material_is_cookable(u8 content) bool item_material_is_cookable(content_t content)
{ {
if(content == CONTENT_TREE) if(content == CONTENT_TREE)
return true; return true;
@ -34,7 +34,7 @@ bool item_material_is_cookable(u8 content)
return false; return false;
} }
InventoryItem* item_material_create_cook_result(u8 content) InventoryItem* item_material_create_cook_result(content_t content)
{ {
if(content == CONTENT_TREE) if(content == CONTENT_TREE)
return new CraftItem("lump_of_coal", 1); 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 "common_irrlicht.h" // For u8, s16
#include <string> #include <string>
#include "mapnode.h" // For content_t
class InventoryItem; class InventoryItem;
class ServerActiveObject; class ServerActiveObject;
class ServerEnvironment; class ServerEnvironment;
bool item_material_is_cookable(u8 content); bool item_material_is_cookable(content_t content);
InventoryItem* item_material_create_cook_result(u8 content); InventoryItem* item_material_create_cook_result(content_t content);
std::string item_craft_get_image_name(const std::string &subname); std::string item_craft_get_image_name(const std::string &subname);
ServerActiveObject* item_craft_create_object(const std::string &subname, ServerActiveObject* item_craft_create_object(const std::string &subname,

@ -199,7 +199,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add torches to mesh Add torches to mesh
*/ */
if(n.d == CONTENT_TORCH) if(n.getContent() == CONTENT_TORCH)
{ {
video::SColor c(255,255,255,255); video::SColor c(255,255,255,255);
@ -212,7 +212,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0), 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++) for(s32 i=0; i<4; i++)
{ {
@ -262,7 +262,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Signs on walls 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)); u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(255,l,l,l); video::SColor c(255,l,l,l);
@ -277,7 +277,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 0,0), 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++) for(s32 i=0; i<4; i++)
{ {
@ -317,16 +317,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add flowing water to mesh Add flowing water to mesh
*/ */
else if(n.d == CONTENT_WATER) else if(n.getContent() == CONTENT_WATER)
{ {
bool top_is_water = false; bool top_is_water = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); 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; top_is_water = true;
u8 l = 0; u8 l = 0;
// Use the light of the node on top if possible // 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)); l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
// Otherwise use the light of this node (the water) // Otherwise use the light of this node (the water)
else else
@ -336,7 +336,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// Neighbor water levels (key = relative position) // Neighbor water levels (key = relative position)
// Includes current node // Includes current node
core::map<v3s16, f32> neighbor_levels; 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; core::map<v3s16, u8> neighbor_flags;
const u8 neighborflag_top_is_water = 0x01; const u8 neighborflag_top_is_water = 0x01;
v3s16 neighbor_dirs[9] = { v3s16 neighbor_dirs[9] = {
@ -358,13 +358,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// Check neighbor // Check neighbor
v3s16 p2 = p + neighbor_dirs[i]; v3s16 p2 = p + neighbor_dirs[i];
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); 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; level = (-0.5+node_water_level) * BS;
else if(n2.d == CONTENT_WATER) else if(n2.getContent() == CONTENT_WATER)
level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0 level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
* node_water_level) * BS; * node_water_level) * BS;
@ -373,7 +373,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// doesn't exist // doesn't exist
p2.Y += 1; p2.Y += 1;
n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); 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; flags |= neighborflag_top_is_water;
} }
@ -581,14 +581,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add water sources to mesh if using new style 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_water = false;
bool top_is_air = false; bool top_is_air = false;
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); 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;*/ top_is_water = true;*/
if(n.d == CONTENT_AIR) if(n.getContent() == CONTENT_AIR)
top_is_air = true; top_is_air = true;
/*if(top_is_water == true) /*if(top_is_water == true)
@ -628,7 +628,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add leaves if using new style 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(n.getLightBlend(data->m_daynight_ratio));*/
u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
@ -696,7 +696,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add glass 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))); u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c(255,l,l,l); video::SColor c(255,l,l,l);
@ -759,7 +759,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add fence 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))); u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
video::SColor c(255,l,l,l); video::SColor c(255,l,l,l);
@ -785,7 +785,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 p2 = p; v3s16 p2 = p;
p2.X++; p2.X++;
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); 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 = intToFloat(p+blockpos_nodes, BS);
pos.X += BS/2; pos.X += BS/2;
@ -811,7 +811,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
p2 = p; p2 = p;
p2.Z++; p2.Z++;
n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); 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 = intToFloat(p+blockpos_nodes, BS);
pos.Z += BS/2; pos.Z += BS/2;
@ -838,7 +838,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add stones with minerals if stone is invisible 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++) for(u32 j=0; j<6; j++)
{ {
@ -846,7 +846,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 dir = g_6dirs[j]; v3s16 dir = g_6dirs[j];
/*u8 l = 0; /*u8 l = 0;
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir); 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)); l = decode_light(n2.getLightBlend(data->m_daynight_ratio));
else else
l = 255;*/ l = 255;*/

@ -31,6 +31,59 @@ void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness)
void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness); void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness);
void setWoodLikeDiggingProperties(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},
};
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() void content_mapnode_init()
{ {
// Read some settings // Read some settings
@ -38,7 +91,7 @@ void content_mapnode_init()
bool new_style_leaves = g_settings.getBool("new_style_leaves"); bool new_style_leaves = g_settings.getBool("new_style_leaves");
bool invisible_stone = g_settings.getBool("invisible_stone"); bool invisible_stone = g_settings.getBool("invisible_stone");
u8 i; content_t i;
ContentFeatures *f = NULL; ContentFeatures *f = NULL;
i = CONTENT_STONE; i = CONTENT_STONE;

@ -20,36 +20,48 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CONTENT_MAPNODE_HEADER #ifndef CONTENT_MAPNODE_HEADER
#define CONTENT_MAPNODE_HEADER #define CONTENT_MAPNODE_HEADER
#include "mapnode.h"
void content_mapnode_init(); 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 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 is needed.
#define CONTENT_STONE 0 #define CONTENT_STONE 0
#define CONTENT_GRASS 1
#define CONTENT_WATER 2 #define CONTENT_WATER 2
#define CONTENT_TORCH 3 #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 #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_SIGN_WALL 14
#define CONTENT_CHEST 15 #define CONTENT_CHEST 15
#define CONTENT_FURNACE 16 #define CONTENT_FURNACE 16
//#define CONTENT_WORKBENCH 17 //#define CONTENT_WORKBENCH 17
#define CONTENT_COBBLE 18
#define CONTENT_STEEL 19
#define CONTENT_GLASS 20
#define CONTENT_FENCE 21 #define CONTENT_FENCE 21
#define CONTENT_MOSSYCOBBLE 22
#define CONTENT_GRAVEL 23 // 0x800...0xfff: param2 higher 4 bytes 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
#endif #endif

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

@ -417,7 +417,7 @@ void getPointedNode(Client *client, v3f player_position,
try try
{ {
n = client->getNode(v3s16(x,y,z)); n = client->getNode(v3s16(x,y,z));
if(content_pointable(n.d) == false) if(content_pointable(n.getContent()) == false)
continue; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -442,9 +442,9 @@ void getPointedNode(Client *client, v3f player_position,
/* /*
Meta-objects 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); v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20; dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f; 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); v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
dir_f *= BS/2 - BS/6 - BS/20; dir_f *= BS/2 - BS/6 - BS/20;
v3f cpf = npf + dir_f; v3f cpf = npf + dir_f;
@ -1722,7 +1722,7 @@ void the_game(
} }
// Get digging properties for material and tool // Get digging properties for material and tool
u8 material = n.d; content_t material = n.getContent();
DiggingProperties prop = DiggingProperties prop =
getDiggingProperties(material, toolname); getDiggingProperties(material, toolname);

@ -61,7 +61,7 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
is>>material; is>>material;
u16 count; u16 count;
is>>count; is>>count;
if(material > 255) if(material > MAX_CONTENT)
throw SerializationError("Too large material number"); throw SerializationError("Too large material number");
return new MaterialItem(material, count); 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 "common_irrlicht.h"
#include "debug.h" #include "debug.h"
#include "mapblockobject.h" #include "mapblockobject.h"
// For g_materials #include "main.h" // For g_materials
#include "main.h" #include "mapnode.h" // For content_t
#define QUANTITY_ITEM_MAX_COUNT 99 #define QUANTITY_ITEM_MAX_COUNT 99
@ -113,7 +113,7 @@ protected:
class MaterialItem : public InventoryItem class MaterialItem : public InventoryItem
{ {
public: public:
MaterialItem(u8 content, u16 count): MaterialItem(content_t content, u16 count):
InventoryItem(count) InventoryItem(count)
{ {
m_content = content; m_content = content;
@ -175,12 +175,12 @@ public:
/* /*
Special methods Special methods
*/ */
u8 getMaterial() content_t getMaterial()
{ {
return m_content; return m_content;
} }
private: private:
u8 m_content; content_t m_content;
}; };
//TODO: Remove //TODO: Remove

@ -54,6 +54,24 @@ A list of "active blocks" in which stuff happens. (+=done)
+ This was left to be done by the old system and it sends only the + This was left to be done by the old system and it sends only the
nearest ones. nearest ones.
Vim conversion regexpes for moving to extended content type storage:
%s/\(\.\|->\)d \([!=]=\)/\1getContent() \2/g
%s/content_features(\([^.]*\)\.d)/content_features(\1)/g
%s/\(\.\|->\)d = \([^;]*\);/\1setContent(\2);/g
%s/\(getNodeNoExNoEmerge([^)]*)\)\.d/\1.getContent()/g
%s/\(getNodeNoExNoEmerge(.*)\)\.d/\1.getContent()/g
%s/\.d;/.getContent();/g
%s/\(content_liquid\|content_flowing_liquid\|make_liquid_flowing\|content_pointable\)(\([^.]*\).d)/\1(\2.getContent())/g
Other things to note:
- node.d = node.param0 (only in raw serialization; use getContent() otherwise)
- node.param = node.param1
- node.dir = node.param2
- content_walkable(node.d) etc should be changed to
content_features(node).walkable etc
- Also check for lines that store the result of getContent to a 8-bit
variable and fix them (result of getContent() must be stored in
content_t, which is 16-bit)
Old, wild and random suggestions that probably won't be done: Old, wild and random suggestions that probably won't be done:
------------------------------------------------------------- -------------------------------------------------------------
@ -337,7 +355,7 @@ TODO: Restart irrlicht completely when coming back to main menu from game.
TODO: Merge bahamada's audio stuff (clean patch available) TODO: Merge bahamada's audio stuff (clean patch available)
TODO: Merge key configuration menu (no clean patch available) TODO: Move content_features to mapnode_content_features.{h,cpp} or so
Making it more portable: Making it more portable:
------------------------ ------------------------

@ -630,9 +630,9 @@ s16 Map::propagateSunlight(v3s16 start,
else else
{ {
/*// Turn mud into grass /*// 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); block->setNode(relpos, n);
modified_blocks.insert(blockpos, block); 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 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{ try{
MapNode bottomnode = getNode(bottompos); MapNode bottomnode = getNode(bottompos);
if(bottomnode.d == CONTENT_GRASS if(bottomnode.getContent() == CONTENT_GRASS
|| bottomnode.d == CONTENT_GRASS_FOOTSTEPS) || bottomnode.getContent() == CONTENT_GRASS_FOOTSTEPS)
{ {
bottomnode.d = CONTENT_MUD; bottomnode.setContent(CONTENT_MUD);
setNode(bottompos, bottomnode); 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 If the new node is mud and it is under sunlight, change it
to grass 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 #endif
@ -986,7 +986,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
If node lets sunlight through and is under sunlight, it has If node lets sunlight through and is under sunlight, it has
sunlight too. 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); n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
} }
@ -1001,7 +1001,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
Add intial metadata Add intial metadata
*/ */
NodeMetadata *meta_proto = content_features(n.d).initial_metadata; NodeMetadata *meta_proto = content_features(n).initial_metadata;
if(meta_proto) if(meta_proto)
{ {
NodeMetadata *meta = meta_proto->clone(); 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 TODO: This could be optimized by mass-unlighting instead
of looping 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; s16 y = p.Y - 1;
for(;; y--){ for(;; y--){
@ -1086,7 +1086,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
v3s16 p2 = p + dirs[i]; v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2); MapNode n2 = getNode(p2);
if(content_liquid(n2.d)) if(content_liquid(n2.getContent()))
{ {
m_transforming_liquid.push_back(p2); m_transforming_liquid.push_back(p2);
} }
@ -1111,7 +1111,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
v3s16 toppos = p + v3s16(0,1,0); v3s16 toppos = p + v3s16(0,1,0);
// Node will be replaced with this // 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, If there is a node at top and it doesn't have sunlight,
@ -1158,7 +1158,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
*/ */
MapNode n; MapNode n;
n.d = replace_material; n.setContent(replace_material);
setNode(p, n); setNode(p, n);
for(s32 i=0; i<2; i++) for(s32 i=0; i<2; i++)
@ -1258,7 +1258,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
v3s16 p2 = p + dirs[i]; v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2); MapNode n2 = getNode(p2);
if(content_liquid(n2.d)) if(content_liquid(n2.getContent()))
{ {
m_transforming_liquid.push_back(p2); m_transforming_liquid.push_back(p2);
} }
@ -1559,17 +1559,17 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
MapNode n0 = getNodeNoEx(p0); MapNode n0 = getNodeNoEx(p0);
// Don't deal with non-liquids // Don't deal with non-liquids
if(content_liquid(n0.d) == false) if(content_liquid(n0.getContent()) == false)
continue; continue;
bool is_source = !content_flowing_liquid(n0.d); bool is_source = !content_flowing_liquid(n0.getContent());
u8 liquid_level = 8; u8 liquid_level = 8;
if(is_source == false) if(is_source == false)
liquid_level = n0.param2 & 0x0f; liquid_level = n0.param2 & 0x0f;
// Turn possible source into non-source // Turn possible source into non-source
u8 nonsource_c = make_liquid_flowing(n0.d); u8 nonsource_c = make_liquid_flowing(n0.getContent());
/* /*
If not source, check that some node flows into this one If not source, check that some node flows into this one
@ -1593,9 +1593,9 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
v3s16 p2 = p0 + dirs_from[i]; v3s16 p2 = p0 + dirs_from[i];
MapNode n2 = getNodeNoEx(p2); MapNode n2 = getNodeNoEx(p2);
if(content_liquid(n2.d)) if(content_liquid(n2.getContent()))
{ {
u8 n2_nonsource_c = make_liquid_flowing(n2.d); u8 n2_nonsource_c = make_liquid_flowing(n2.getContent());
// Check that the liquids are the same type // Check that the liquids are the same type
if(n2_nonsource_c != nonsource_c) if(n2_nonsource_c != nonsource_c)
{ {
@ -1603,7 +1603,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
" collide"<<std::endl; " collide"<<std::endl;
continue; continue;
} }
bool n2_is_source = !content_flowing_liquid(n2.d); bool n2_is_source = !content_flowing_liquid(n2.getContent());
s8 n2_liquid_level = 8; s8 n2_liquid_level = 8;
if(n2_is_source == false) if(n2_is_source == false)
n2_liquid_level = n2.param2 & 0x07; n2_liquid_level = n2.param2 & 0x07;
@ -1636,7 +1636,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
if(new_liquid_level_max == -1) if(new_liquid_level_max == -1)
{ {
// Remove water alltoghether // Remove water alltoghether
n0.d = CONTENT_AIR; n0.setContent(CONTENT_AIR);
n0.param2 = 0; n0.param2 = 0;
setNode(p0, n0); setNode(p0, n0);
} }
@ -1670,7 +1670,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
v3s16 p2 = p0 + dirs[i]; v3s16 p2 = p0 + dirs[i];
MapNode n2 = getNodeNoEx(p2); MapNode n2 = getNodeNoEx(p2);
if(content_flowing_liquid(n2.d)) if(content_flowing_liquid(n2.getContent()))
{ {
m_transforming_liquid.push_back(p2); m_transforming_liquid.push_back(p2);
} }
@ -1679,7 +1679,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
} }
// Get a new one from queue if the node has turned into non-water // Get a new one from queue if the node has turned into non-water
if(content_liquid(n0.d) == false) if(content_liquid(n0.getContent()) == false)
continue; continue;
/* /*
@ -1722,9 +1722,9 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
MapNode n2 = getNodeNoEx(p2); MapNode n2 = getNodeNoEx(p2);
//dstream<<"[1] n2.param="<<(int)n2.param<<std::endl; //dstream<<"[1] n2.param="<<(int)n2.param<<std::endl;
if(content_liquid(n2.d)) if(content_liquid(n2.getContent()))
{ {
u8 n2_nonsource_c = make_liquid_flowing(n2.d); u8 n2_nonsource_c = make_liquid_flowing(n2.getContent());
// Check that the liquids are the same type // Check that the liquids are the same type
if(n2_nonsource_c != nonsource_c) if(n2_nonsource_c != nonsource_c)
{ {
@ -1732,7 +1732,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
" collide"<<std::endl; " collide"<<std::endl;
continue; continue;
} }
bool n2_is_source = !content_flowing_liquid(n2.d); bool n2_is_source = !content_flowing_liquid(n2.getContent());
u8 n2_liquid_level = 8; u8 n2_liquid_level = 8;
if(n2_is_source == false) if(n2_is_source == false)
n2_liquid_level = n2.param2 & 0x07; n2_liquid_level = n2.param2 & 0x07;
@ -1760,9 +1760,9 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
} }
} }
} }
else if(n2.d == CONTENT_AIR) else if(n2.getContent() == CONTENT_AIR)
{ {
n2.d = nonsource_c; n2.setContent(nonsource_c);
n2.param2 = liquid_next_level; n2.param2 = liquid_next_level;
setNode(p2, n2); setNode(p2, n2);
@ -2362,7 +2362,7 @@ MapBlock * ServerMap::generateBlock(
{ {
v3s16 p(x0,y0,z0); v3s16 p(x0,y0,z0);
MapNode n = block->getNode(p); MapNode n = block->getNode(p);
if(n.d == CONTENT_IGNORE) if(n.getContent() == CONTENT_IGNORE)
{ {
dstream<<"CONTENT_IGNORE at " dstream<<"CONTENT_IGNORE at "
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@ -2391,9 +2391,9 @@ MapBlock * ServerMap::generateBlock(
{ {
MapNode n; MapNode n;
if(y0%2==0) if(y0%2==0)
n.d = CONTENT_AIR; n.setContent(CONTENT_AIR);
else else
n.d = CONTENT_STONE; n.setContent(CONTENT_STONE);
block->setNode(v3s16(x0,y0,z0), n); block->setNode(v3s16(x0,y0,z0), n);
} }
} }
@ -2674,19 +2674,19 @@ s16 ServerMap::findGroundLevel(v2s16 p2d)
for(; p.Y>min; p.Y--) for(; p.Y>min; p.Y--)
{ {
MapNode n = getNodeNoEx(p); MapNode n = getNodeNoEx(p);
if(n.d != CONTENT_IGNORE) if(n.getContent() != CONTENT_IGNORE)
break; break;
} }
if(p.Y == min) if(p.Y == min)
goto plan_b; goto plan_b;
// If this node is not air, go to 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; goto plan_b;
// Search existing walkable and return it // Search existing walkable and return it
for(; p.Y>min; p.Y--) for(; p.Y>min; p.Y--)
{ {
MapNode n = getNodeNoEx(p); 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; return p.Y;
} }

@ -242,7 +242,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
// Check if node above block has sunlight // Check if node above block has sunlight
try{ try{
MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z)); MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
if(n.d == CONTENT_IGNORE || n.getLight(LIGHTBANK_DAY) != LIGHT_SUN) if(n.getContent() == CONTENT_IGNORE || n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
{ {
no_sunlight = true; no_sunlight = true;
} }
@ -260,8 +260,8 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
else else
{ {
MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z)); MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
//if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE) //if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
if(content_features(n.d).sunlight_propagates == false) if(content_features(n).sunlight_propagates == false)
{ {
no_sunlight = true; no_sunlight = true;
} }
@ -322,14 +322,14 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
bool upper_is_air = false; bool upper_is_air = false;
try 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; upper_is_air = true;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
{ {
} }
// Turn mud into grass // Turn mud into grass
if(upper_is_air && n.d == CONTENT_MUD if(upper_is_air && n.getContent() == CONTENT_MUD
&& current_light == LIGHT_SUN) && current_light == LIGHT_SUN)
{ {
n.d = CONTENT_GRASS; n.d = CONTENT_GRASS;
@ -473,7 +473,7 @@ void MapBlock::updateDayNightDiff()
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++) for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
{ {
MapNode &n = data[i]; MapNode &n = data[i];
if(n.d != CONTENT_AIR) if(n.getContent() != CONTENT_AIR)
{ {
only_air = false; only_air = false;
break; break;
@ -496,8 +496,8 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
s16 y = MAP_BLOCKSIZE-1; s16 y = MAP_BLOCKSIZE-1;
for(; y>=0; y--) for(; y>=0; y--)
{ {
//if(is_ground_content(getNodeRef(p2d.X, y, p2d.Y).d)) MapNode n = getNodeRef(p2d.X, y, p2d.Y);
if(content_features(getNodeRef(p2d.X, y, p2d.Y).d).walkable) if(content_features(n).walkable)
{ {
if(y == MAP_BLOCKSIZE-1) if(y == MAP_BLOCKSIZE-1)
return -2; return -2;
@ -560,7 +560,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
SharedBuffer<u8> materialdata(nodecount); SharedBuffer<u8> materialdata(nodecount);
for(u32 i=0; i<nodecount; i++) for(u32 i=0; i<nodecount; i++)
{ {
materialdata[i] = data[i].d; materialdata[i] = data[i].param0;
} }
compress(materialdata, os, version); compress(materialdata, os, version);
@ -568,7 +568,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
SharedBuffer<u8> lightdata(nodecount); SharedBuffer<u8> lightdata(nodecount);
for(u32 i=0; i<nodecount; i++) for(u32 i=0; i<nodecount; i++)
{ {
lightdata[i] = data[i].param; lightdata[i] = data[i].param1;
} }
compress(lightdata, os, version); compress(lightdata, os, version);
@ -715,7 +715,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
("MapBlock::deSerialize: invalid format"); ("MapBlock::deSerialize: invalid format");
for(u32 i=0; i<s.size(); i++) for(u32 i=0; i<s.size(); i++)
{ {
data[i].d = s[i]; data[i].param0 = s[i];
} }
} }
{ {
@ -728,7 +728,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
("MapBlock::deSerialize: invalid format"); ("MapBlock::deSerialize: invalid format");
for(u32 i=0; i<s.size(); i++) for(u32 i=0; i<s.size(); i++)
{ {
data[i].param = s[i]; data[i].param1 = s[i];
} }
} }

@ -285,7 +285,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
return spec; 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 Check temporary modifications on this node
@ -320,7 +320,7 @@ u8 getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
} }
} }
return mn.d; return mn.getContent();
} }
v3s16 dirs8[8] = { v3s16 dirs8[8] = {
@ -343,16 +343,16 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
for(u32 i=0; i<8; i++) for(u32 i=0; i<8; i++)
{ {
MapNode n = vmanip.getNodeNoEx(p - dirs8[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 // 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 += decode_light(n.getLightBlend(daynight_ratio));
light_count++; light_count++;
} }
else else
{ {
if(n.d != CONTENT_IGNORE) if(n.getContent() != CONTENT_IGNORE)
ambient_occlusion++; ambient_occlusion++;
} }
} }
@ -408,8 +408,8 @@ void getTileInfo(
TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods); TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
// This is hackish // This is hackish
u8 content0 = getNodeContent(p, n0, temp_mods); content_t content0 = getNodeContent(p, n0, temp_mods);
u8 content1 = getNodeContent(p + face_dir, n1, temp_mods); content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
u8 mf = face_contents(content0, content1); u8 mf = face_contents(content0, content1);
if(mf == 0) if(mf == 0)

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

@ -67,8 +67,8 @@ static s16 find_ground_level_clever(VoxelManipulator &vmanip, v2s16 p2d)
{ {
MapNode &n = vmanip.m_data[i]; MapNode &n = vmanip.m_data[i];
if(content_walkable(n.d) if(content_walkable(n.d)
&& n.d != CONTENT_TREE && n.getContent() != CONTENT_TREE
&& n.d != CONTENT_LEAVES) && n.getContent() != CONTENT_LEAVES)
break; break;
vmanip.m_area.add_y(em, i, -1); vmanip.m_area.add_y(em, i, -1);
@ -143,8 +143,8 @@ static void make_tree(VoxelManipulator &vmanip, v3s16 p0)
if(vmanip.m_area.contains(p) == false) if(vmanip.m_area.contains(p) == false)
continue; continue;
u32 vi = vmanip.m_area.index(p); u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d != CONTENT_AIR if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].d != CONTENT_IGNORE) && vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue; continue;
u32 i = leaves_a.index(x,y,z); u32 i = leaves_a.index(x,y,z);
if(leaves_d[i] == 1) if(leaves_d[i] == 1)
@ -223,8 +223,8 @@ static void make_randomstone(VoxelManipulator &vmanip, v3s16 p0)
if(vmanip.m_area.contains(p) == false) if(vmanip.m_area.contains(p) == false)
continue; continue;
u32 vi = vmanip.m_area.index(p); u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].d != CONTENT_AIR if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].d != CONTENT_IGNORE) && vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue; continue;
u32 i = stone_a.index(x,y,z); u32 i = stone_a.index(x,y,z);
if(stone_d[i] == 1) if(stone_d[i] == 1)
@ -307,8 +307,8 @@ static void make_largestone(VoxelManipulator &vmanip, v3s16 p0)
if(vmanip.m_area.contains(p) == false) if(vmanip.m_area.contains(p) == false)
continue; continue;
u32 vi = vmanip.m_area.index(p); u32 vi = vmanip.m_area.index(p);
/*if(vmanip.m_data[vi].d != CONTENT_AIR /*if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].d != CONTENT_IGNORE) && vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;*/ continue;*/
u32 i = stone_a.index(x,y,z); u32 i = stone_a.index(x,y,z);
if(stone_d[i] == 1) if(stone_d[i] == 1)
@ -516,9 +516,9 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace,
p.Y += make_stairs; p.Y += make_stairs;
/*// If already empty /*// If already empty
if(vmanip.getNodeNoExNoEmerge(p).d if(vmanip.getNodeNoExNoEmerge(p).getContent()
== CONTENT_AIR == CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d && vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
== CONTENT_AIR) == CONTENT_AIR)
{ {
}*/ }*/
@ -614,9 +614,9 @@ public:
randomizeDir(); randomizeDir();
continue; continue;
} }
if(vmanip.getNodeNoExNoEmerge(p).d if(vmanip.getNodeNoExNoEmerge(p).getContent()
== CONTENT_COBBLE == CONTENT_COBBLE
&& vmanip.getNodeNoExNoEmerge(p1).d && vmanip.getNodeNoExNoEmerge(p1).getContent()
== CONTENT_COBBLE) == CONTENT_COBBLE)
{ {
// Found wall, this is a good place! // Found wall, this is a good place!
@ -630,25 +630,25 @@ public:
Determine where to move next Determine where to move next
*/ */
// Jump one up if the actual space is there // 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 == CONTENT_COBBLE
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d && vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
== CONTENT_AIR == CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,2,0)).d && vmanip.getNodeNoExNoEmerge(p+v3s16(0,2,0)).getContent()
== CONTENT_AIR) == CONTENT_AIR)
p += v3s16(0,1,0); p += v3s16(0,1,0);
// Jump one down if the actual space is there // 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 == CONTENT_COBBLE
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).d && vmanip.getNodeNoExNoEmerge(p+v3s16(0,0,0)).getContent()
== CONTENT_AIR == CONTENT_AIR
&& vmanip.getNodeNoExNoEmerge(p+v3s16(0,-1,0)).d && vmanip.getNodeNoExNoEmerge(p+v3s16(0,-1,0)).getContent()
== CONTENT_AIR) == CONTENT_AIR)
p += v3s16(0,-1,0); p += v3s16(0,-1,0);
// Check if walking is now possible // Check if walking is now possible
if(vmanip.getNodeNoExNoEmerge(p).d if(vmanip.getNodeNoExNoEmerge(p).getContent()
!= CONTENT_AIR != CONTENT_AIR
|| vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).d || vmanip.getNodeNoExNoEmerge(p+v3s16(0,1,0)).getContent()
!= CONTENT_AIR) != CONTENT_AIR)
{ {
// Cannot continue walking here // Cannot continue walking here
@ -770,7 +770,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random)
fits = false; fits = false;
break; break;
} }
if(vmanip.m_data[vi].d == CONTENT_IGNORE) if(vmanip.m_data[vi].getContent() == CONTENT_IGNORE)
{ {
fits = false; fits = false;
break; break;
@ -1245,11 +1245,11 @@ void add_random_objects(MapBlock *block)
{ {
v3s16 p(x0,y0,z0); v3s16 p(x0,y0,z0);
MapNode n = block->getNodeNoEx(p); MapNode n = block->getNodeNoEx(p);
if(n.d == CONTENT_IGNORE) if(n.getContent() == CONTENT_IGNORE)
continue; continue;
if(content_features(n.d).liquid_type != LIQUID_NONE) if(content_features(n).liquid_type != LIQUID_NONE)
continue; continue;
if(content_features(n.d).walkable) if(content_features(n).walkable)
{ {
last_node_walkable = true; last_node_walkable = true;
continue; continue;
@ -1257,7 +1257,7 @@ void add_random_objects(MapBlock *block)
if(last_node_walkable) if(last_node_walkable)
{ {
// If block contains light information // 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) if(n.getLight(LIGHTBANK_DAY) <= 3)
{ {
@ -1363,7 +1363,7 @@ void make_block(BlockMakeData *data)
for(s16 y=node_min.Y; y<=node_max.Y; y++) for(s16 y=node_min.Y; y<=node_max.Y; y++)
{ {
// Only modify places that have no content // 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) if(y <= WATER_LEVEL)
vmanip.m_data[i] = MapNode(CONTENT_WATERSOURCE); vmanip.m_data[i] = MapNode(CONTENT_WATERSOURCE);
@ -1468,7 +1468,7 @@ void make_block(BlockMakeData *data)
for(s16 y=node_min.Y; y<=node_max.Y; y++) for(s16 y=node_min.Y; y<=node_max.Y; y++)
{ {
// Only modify places that have no content // 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. // First priority: make air and water.
// This avoids caves inside water. // This avoids caves inside water.
@ -1513,7 +1513,7 @@ void make_block(BlockMakeData *data)
{ {
v3s16 p = v3s16(x,y,z) + g_27dirs[i]; v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p); 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) if(mineralrandom.next()%8 == 0)
vmanip.m_data[vi] = MapNode(CONTENT_MESE); vmanip.m_data[vi] = MapNode(CONTENT_MESE);
} }
@ -1554,13 +1554,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++) for(u16 i=0; i<27; i++)
{ {
v3s16 p = v3s16(x,y,z) + g_27dirs[i]; v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p); 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) if(mineralrandom.next()%sparseness == 0)
vmanip.m_data[vi] = new_content; vmanip.m_data[vi] = new_content;
@ -1591,7 +1591,7 @@ void make_block(BlockMakeData *data)
{ {
v3s16 p = v3s16(x,y,z) + g_27dirs[i]; v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p); 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) if(mineralrandom.next()%8 == 0)
vmanip.m_data[vi] = MapNode(CONTENT_STONE, MINERAL_COAL); vmanip.m_data[vi] = MapNode(CONTENT_STONE, MINERAL_COAL);
} }
@ -1617,7 +1617,7 @@ void make_block(BlockMakeData *data)
{ {
v3s16 p = v3s16(x,y,z) + g_27dirs[i]; v3s16 p = v3s16(x,y,z) + g_27dirs[i];
u32 vi = vmanip.m_area.index(p); 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) if(mineralrandom.next()%8 == 0)
vmanip.m_data[vi] = MapNode(CONTENT_STONE, MINERAL_IRON); vmanip.m_data[vi] = MapNode(CONTENT_STONE, MINERAL_IRON);
} }
@ -1640,7 +1640,7 @@ void make_block(BlockMakeData *data)
u32 i = vmanip.m_area.index(v3s16(p2d.X, node_max.Y, p2d.Y)); 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--) 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) if(noisebuf_ground_crumbleness.get(x,y,z) > 1.3)
{ {
@ -1692,9 +1692,9 @@ void make_block(BlockMakeData *data)
u32 i = vmanip.m_area.index(v3s16(p2d.X, full_node_max.Y, p2d.Y)); 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--) 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; 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; vmanip.m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
data->vmanip->m_area.add_y(em, i, -1); data->vmanip->m_area.add_y(em, i, -1);
} }
@ -1725,17 +1725,17 @@ void make_block(BlockMakeData *data)
double d = noise3d_perlin((float)x/2.5, double d = noise3d_perlin((float)x/2.5,
(float)y/2.5,(float)z/2.5, (float)y/2.5,(float)z/2.5,
blockseed, 2, 1.4); 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) 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) /*else if(vmanip.m_flags[i] & VMANIP_FLAG_DUNGEON_INSIDE)
{ {
if(wetness > 1.2) 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); data->vmanip->m_area.add_y(em, i, -1);
} }
@ -1761,7 +1761,7 @@ void make_block(BlockMakeData *data)
{ {
if(water_found == false) 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); v3s16 p = v3s16(p2d.X, y, p2d.Y);
data->transforming_liquid.push_back(p); data->transforming_liquid.push_back(p);
@ -1773,7 +1773,7 @@ void make_block(BlockMakeData *data)
// This can be done because water_found can only // This can be done because water_found can only
// turn to true and end up here after going through // turn to true and end up here after going through
// a single block. // 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); v3s16 p = v3s16(p2d.X, y+1, p2d.Y);
data->transforming_liquid.push_back(p); data->transforming_liquid.push_back(p);
@ -1814,16 +1814,16 @@ void make_block(BlockMakeData *data)
u32 i = vmanip.m_area.index(v3s16(p2d.X, start_y, p2d.Y)); u32 i = vmanip.m_area.index(v3s16(p2d.X, start_y, p2d.Y));
for(s16 y=start_y; y>=node_min.Y-3; 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; water_detected = true;
if(vmanip.m_data[i].d == CONTENT_AIR) if(vmanip.m_data[i].getContent() == CONTENT_AIR)
air_detected = true; air_detected = true;
if((vmanip.m_data[i].d == CONTENT_STONE if((vmanip.m_data[i].getContent() == CONTENT_STONE
|| vmanip.m_data[i].d == CONTENT_GRASS || vmanip.m_data[i].getContent() == CONTENT_GRASS
|| vmanip.m_data[i].d == CONTENT_MUD || vmanip.m_data[i].getContent() == CONTENT_MUD
|| vmanip.m_data[i].d == CONTENT_SAND || vmanip.m_data[i].getContent() == CONTENT_SAND
|| vmanip.m_data[i].d == CONTENT_GRAVEL || vmanip.m_data[i].getContent() == CONTENT_GRAVEL
) && (air_detected || water_detected)) ) && (air_detected || water_detected))
{ {
if(current_depth == 0 && y <= WATER_LEVEL+2 if(current_depth == 0 && y <= WATER_LEVEL+2
@ -1846,8 +1846,8 @@ void make_block(BlockMakeData *data)
} }
else else
{ {
if(vmanip.m_data[i].d == CONTENT_MUD if(vmanip.m_data[i].getContent() == CONTENT_MUD
|| vmanip.m_data[i].d == CONTENT_GRASS) || vmanip.m_data[i].getContent() == CONTENT_GRASS)
vmanip.m_data[i] = MapNode(CONTENT_STONE); vmanip.m_data[i] = MapNode(CONTENT_STONE);
} }
@ -1894,7 +1894,7 @@ void make_block(BlockMakeData *data)
{ {
u32 i = data->vmanip->m_area.index(p); u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i]; MapNode *n = &data->vmanip->m_data[i];
if(n->d != CONTENT_AIR && n->d != CONTENT_IGNORE) if(n->getContent() != CONTENT_AIR && n->getContent() != CONTENT_IGNORE)
{ {
found = true; found = true;
break; break;
@ -1909,7 +1909,7 @@ void make_block(BlockMakeData *data)
{ {
u32 i = data->vmanip->m_area.index(p); u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i]; 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; continue;
} }
// Tree will be placed one higher // Tree will be placed one higher
@ -1942,7 +1942,7 @@ void make_block(BlockMakeData *data)
/*{ /*{
u32 i = data->vmanip->m_area.index(v3s16(p)); u32 i = data->vmanip->m_area.index(v3s16(p));
MapNode *n = &data->vmanip->m_data[i]; 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; continue;
}*/ }*/
// Will be placed one higher // Will be placed one higher
@ -1977,7 +1977,7 @@ void make_block(BlockMakeData *data)
/*{ /*{
u32 i = data->vmanip->m_area.index(v3s16(p)); u32 i = data->vmanip->m_area.index(v3s16(p));
MapNode *n = &data->vmanip->m_data[i]; 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; continue;
}*/ }*/
// Will be placed one lower // Will be placed one lower

@ -30,8 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
ContentFeatures::~ContentFeatures() ContentFeatures::~ContentFeatures()
{ {
/*if(translate_to)
delete translate_to;*/
if(initial_metadata) if(initial_metadata)
delete initial_metadata; delete initial_metadata;
} }
@ -83,12 +81,16 @@ void ContentFeatures::setInventoryTextureCube(std::string top,
inventory_texture = g_texturesource->getTextureRaw(imgname_full); 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]; return g_content_features[i];
} }
ContentFeatures & content_features(MapNode &n)
{
return content_features(n.getContent());
}
/* /*
See mapnode.h for description. See mapnode.h for description.
@ -128,7 +130,7 @@ void init_mapnode()
initial_material_type = MATERIAL_ALPHA_SIMPLE; initial_material_type = MATERIAL_ALPHA_SIMPLE;
else else
initial_material_type = MATERIAL_ALPHA_NONE;*/ 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]; ContentFeatures *f = &g_content_features[i];
// Re-initialize // Re-initialize
@ -142,7 +144,7 @@ void init_mapnode()
Initially set every block to be shown as an unknown block. Initially set every block to be shown as an unknown block.
Don't touch CONTENT_IGNORE or CONTENT_AIR. 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) if(i == CONTENT_IGNORE || i == CONTENT_AIR)
continue; continue;
@ -183,7 +185,7 @@ v3s16 facedir_rotate(u8 facedir, v3s16 dir)
TileSpec MapNode::getTile(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); dir = facedir_rotate(param1, dir);
TileSpec spec; TileSpec spec;
@ -207,16 +209,16 @@ TileSpec MapNode::getTile(v3s16 dir)
if(dir_i == -1) if(dir_i == -1)
// Non-directional // Non-directional
spec = content_features(d).tiles[0]; spec = content_features(*this).tiles[0];
else else
spec = content_features(d).tiles[dir_i]; spec = content_features(*this).tiles[dir_i];
/* /*
If it contains some mineral, change texture id 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); std::string mineral_texture_name = mineral_block_texture(mineral);
if(mineral_texture_name != "") if(mineral_texture_name != "")
{ {
@ -235,9 +237,9 @@ TileSpec MapNode::getTile(v3s16 dir)
u8 MapNode::getMineral() 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; return MINERAL_NONE;
@ -260,33 +262,36 @@ void MapNode::serialize(u8 *dest, u8 version)
if(!ser_ver_supported(version)) if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported"); 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) if(version <= 18)
{ {
// In these versions, CONTENT_IGNORE and CONTENT_AIR // In these versions, CONTENT_IGNORE and CONTENT_AIR
// are 255 and 254 // are 255 and 254
if(actual_d == CONTENT_IGNORE) if(actual_param0 == CONTENT_IGNORE)
actual_d = 255; actual_param0 = 255;
else if(actual_d == CONTENT_AIR) else if(actual_param0 == CONTENT_AIR)
actual_d = 254; actual_param0 = 254;
} }
if(version == 0) if(version == 0)
{ {
dest[0] = actual_d; dest[0] = actual_param0;
} }
else if(version <= 9) else if(version <= 9)
{ {
dest[0] = actual_d; dest[0] = actual_param0;
dest[1] = param; dest[1] = n_foreign.param1;
} }
else else
{ {
dest[0] = actual_d; dest[0] = actual_param0;
dest[1] = param; dest[1] = n_foreign.param1;
dest[2] = param2; dest[2] = n_foreign.param2;
} }
} }
void MapNode::deSerialize(u8 *source, u8 version) void MapNode::deSerialize(u8 *source, u8 version)
@ -296,47 +301,50 @@ void MapNode::deSerialize(u8 *source, u8 version)
if(version == 0) if(version == 0)
{ {
d = source[0]; param0 = source[0];
} }
else if(version == 1) else if(version == 1)
{ {
d = source[0]; param0 = source[0];
// This version doesn't support saved lighting // This version doesn't support saved lighting
if(light_propagates() || light_source() > 0) if(light_propagates() || light_source() > 0)
param = 0; param1 = 0;
else else
param = source[1]; param1 = source[1];
} }
else if(version <= 9) else if(version <= 9)
{ {
d = source[0]; param0 = source[0];
param = source[1]; param1 = source[1];
} }
else else
{ {
d = source[0]; param0 = source[0];
param = source[1]; param1 = source[1];
param2 = source[2]; param2 = source[2];
} }
// Convert from old version to new // Convert special values from old version to new
if(version <= 18) if(version <= 18)
{ {
// In these versions, CONTENT_IGNORE and CONTENT_AIR // In these versions, CONTENT_IGNORE and CONTENT_AIR
// are 255 and 254 // are 255 and 254
if(d == 255) if(param0 == 255)
d = CONTENT_IGNORE; param0 = CONTENT_IGNORE;
else if(d == 254) else if(param0 == 254)
d = CONTENT_AIR; param0 = CONTENT_AIR;
} }
// version 19 is fucked up with sometimes the old values and sometimes not // version 19 is fucked up with sometimes the old values and sometimes not
if(version == 19) if(version == 19)
{ {
if(d == 255) if(param0 == 255)
d = CONTENT_IGNORE; param0 = CONTENT_IGNORE;
else if(d == 254) else if(param0 == 254)
d = CONTENT_AIR; 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: Naming scheme:
- Material = irrlicht's Material class - 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 - Tile = TileSpec at some side of a node of some content type
*/
/* Content ranges:
Ranges:
0x000...0x07f: param2 is fully usable 0x000...0x07f: param2 is fully usable
0x800...0xfff: param2 lower 4 bytes are free 0x800...0xfff: param2 lower 4 bytes are free
*/ */
typedef u16 content_t; typedef u16 content_t;
#define MAX_CONTENT 0xfff
/* /*
Initializes all kind of stuff in here. Initializes all kind of stuff in here.
@ -102,10 +101,7 @@ class NodeMetadata;
struct ContentFeatures struct ContentFeatures
{ {
// If non-NULL, content is translated to this when deserialized // Type of MapNode::param1
//MapNode *translate_to;
// Type of MapNode::param
ContentParamType param_type; ContentParamType param_type;
/* /*
@ -151,7 +147,7 @@ struct ContentFeatures
// If the content is liquid, this is the flowing version of the liquid. // If the content is liquid, this is the flowing version of the liquid.
// If content is liquid, this is the same content. // If content is liquid, this is the same content.
u8 liquid_alternative_flowing; content_t liquid_alternative_flowing;
// Amount of light the node emits // Amount of light the node emits
u8 light_source; u8 light_source;
@ -163,7 +159,6 @@ struct ContentFeatures
void reset() void reset()
{ {
//translate_to = NULL;
param_type = CPT_NONE; param_type = CPT_NONE;
inventory_texture = NULL; inventory_texture = NULL;
is_ground_content = false; is_ground_content = false;
@ -228,8 +223,8 @@ struct ContentFeatures
/* /*
Call this to access the ContentFeature list 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. Here is a bunch of DEPRECATED functions.
@ -240,7 +235,7 @@ ContentFeatures & content_features(u8 i);
in param. in param.
NOTE: Don't use, use "content_features(m).whatever" instead 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; return content_features(m).light_propagates;
} }
@ -249,7 +244,7 @@ inline bool light_propagates_content(u8 m)
NOTE: It doesn't seem to go through torches regardlessly of this NOTE: It doesn't seem to go through torches regardlessly of this
NOTE: Don't use, use "content_features(m).whatever" instead 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; return content_features(m).sunlight_propagates;
} }
@ -261,35 +256,35 @@ inline bool sunlight_propagates_content(u8 m)
2: Opaque 2: Opaque
NOTE: Don't use, use "content_features(m).whatever" instead 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; return content_features(m).solidness;
} }
// Objects collide with walkable contents // Objects collide with walkable contents
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).walkable;
} }
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).liquid_type != LIQUID_NONE;
} }
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).liquid_type == LIQUID_FLOWING;
} }
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).liquid_type == LIQUID_SOURCE;
} }
// CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER // CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
// CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA // CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; u8 c = content_features(m).liquid_alternative_flowing;
assert(c != CONTENT_IGNORE); assert(c != CONTENT_IGNORE);
@ -297,17 +292,17 @@ inline u8 make_liquid_flowing(u8 m)
} }
// Pointable contents can be pointed to in the map // Pointable contents can be pointed to in the map
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).pointable;
} }
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).diggable;
} }
// NOTE: Don't use, use "content_features(m).whatever" instead // 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; return content_features(m).buildable_to;
} }
@ -319,7 +314,7 @@ inline bool content_buildable_to(u8 m)
1: Face uses m1's content 1: Face uses m1's content
2: Face uses m2'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) if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
return 0; return 0;
@ -416,7 +411,7 @@ struct MapNode
union union
{ {
u8 param0; u8 param0;
u8 d; //u8 d;
}; };
/* /*
@ -431,17 +426,18 @@ struct MapNode
union union
{ {
u8 param1; u8 param1;
s8 param; //s8 param;
}; };
/* /*
The second parameter. Initialized to 0. The second parameter. Initialized to 0.
E.g. direction for torches and flowing water. E.g. direction for torches and flowing water.
If param0 >= 0x80, bits 0xf0 of this is extended content type data
*/ */
union union
{ {
u8 param2; u8 param2;
u8 dir; //u8 dir;
}; };
MapNode(const MapNode & n) MapNode(const MapNode & n)
@ -449,28 +445,44 @@ struct MapNode
*this = n; *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; //param0 = a_param0;
param = a_param; param1 = a_param1;
param2 = a_param2; param2 = a_param2;
// Set after other params because this needs to override part of param2
setContent(content);
} }
bool operator==(const MapNode &other) bool operator==(const MapNode &other)
{ {
return (d == other.d return (param0 == other.param0
&& param == other.param && param1 == other.param1
&& param2 == other.param2); && param2 == other.param2);
} }
// To be used everywhere // To be used everywhere
content_t getContent() content_t getContent()
{ {
return d; if(param0 < 0x80)
return param0;
else
return (param0<<4) + (param2>>4);
} }
void setContent(content_t c) 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;
}
} }
/* /*
@ -478,19 +490,19 @@ struct MapNode
*/ */
bool light_propagates() bool light_propagates()
{ {
return light_propagates_content(d); return light_propagates_content(getContent());
} }
bool sunlight_propagates() bool sunlight_propagates()
{ {
return sunlight_propagates_content(d); return sunlight_propagates_content(getContent());
} }
u8 solidness() u8 solidness()
{ {
return content_solidness(d); return content_solidness(getContent());
} }
u8 light_source() u8 light_source()
{ {
return content_features(d).light_source; return content_features(*this).light_source;
} }
u8 getLightBanksWithSource() u8 getLightBanksWithSource()
@ -498,10 +510,10 @@ struct MapNode
// Select the brightest of [light source, propagated light] // Select the brightest of [light source, propagated light]
u8 lightday = 0; u8 lightday = 0;
u8 lightnight = 0; u8 lightnight = 0;
if(content_features(d).param_type == CPT_LIGHT) if(content_features(*this).param_type == CPT_LIGHT)
{ {
lightday = param & 0x0f; lightday = param1 & 0x0f;
lightnight = (param>>4)&0x0f; lightnight = (param1>>4)&0x0f;
} }
if(light_source() > lightday) if(light_source() > lightday)
lightday = light_source(); lightday = light_source();
@ -514,12 +526,12 @@ struct MapNode
{ {
// Select the brightest of [light source, propagated light] // Select the brightest of [light source, propagated light]
u8 light = 0; u8 light = 0;
if(content_features(d).param_type == CPT_LIGHT) if(content_features(*this).param_type == CPT_LIGHT)
{ {
if(bank == LIGHTBANK_DAY) if(bank == LIGHTBANK_DAY)
light = param & 0x0f; light = param1 & 0x0f;
else if(bank == LIGHTBANK_NIGHT) else if(bank == LIGHTBANK_NIGHT)
light = (param>>4)&0x0f; light = (param1>>4)&0x0f;
else else
assert(0); assert(0);
} }
@ -557,17 +569,17 @@ struct MapNode
void setLight(enum LightBank bank, u8 a_light) void setLight(enum LightBank bank, u8 a_light)
{ {
// If node doesn't contain light data, ignore this // 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; return;
if(bank == LIGHTBANK_DAY) if(bank == LIGHTBANK_DAY)
{ {
param &= 0xf0; param1 &= 0xf0;
param |= a_light & 0x0f; param1 |= a_light & 0x0f;
} }
else if(bank == LIGHTBANK_NIGHT) else if(bank == LIGHTBANK_NIGHT)
{ {
param &= 0x0f; param1 &= 0x0f;
param |= (a_light & 0x0f)<<4; param1 |= (a_light & 0x0f)<<4;
} }
else else
assert(0); assert(0);

@ -3,12 +3,12 @@
// NOTE: DEPRECATED // NOTE: DEPRECATED
DiggingPropertiesList * getDiggingPropertiesList(u8 content) DiggingPropertiesList * getDiggingPropertiesList(u16 content)
{ {
return &content_features(content).digging_properties; 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); DiggingPropertiesList *mprop = getDiggingPropertiesList(content);
if(mprop == NULL) if(mprop == NULL)

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

@ -342,13 +342,13 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
if(in_water) if(in_water)
{ {
v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS); 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 // If not in water, the threshold of going in is at lower y
else else
{ {
v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS); 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) catch(InvalidPositionException &e)
@ -361,7 +361,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
*/ */
try{ try{
v3s16 pp = floatToInt(position + v3f(0,0,0), BS); 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) catch(InvalidPositionException &e)
{ {
@ -470,7 +470,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
{ {
try{ try{
// Player collides into walkable nodes // 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; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -633,10 +633,10 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
try{ try{
// The node to be sneaked on has to be walkable // 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; continue;
// And the node above it has to be nonwalkable // 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; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)

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

@ -2494,7 +2494,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Mandatory parameter; actually used for nothing // Mandatory parameter; actually used for nothing
core::map<v3s16, MapBlock*> modified_blocks; core::map<v3s16, MapBlock*> modified_blocks;
u8 material = CONTENT_IGNORE; content_t material = CONTENT_IGNORE;
u8 mineral = MINERAL_NONE; u8 mineral = MINERAL_NONE;
bool cannot_remove_node = false; bool cannot_remove_node = false;
@ -2505,7 +2505,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Get mineral // Get mineral
mineral = n.getMineral(); mineral = n.getMineral();
// Get material at position // Get material at position
material = n.d; material = n.getContent();
// If not yet cancelled // If not yet cancelled
if(cannot_remove_node == false) if(cannot_remove_node == false)
{ {
@ -2705,7 +2705,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" because privileges are "<<getPlayerPrivs(player) <<" because privileges are "<<getPlayerPrivs(player)
<<std::endl; <<std::endl;
if(content_buildable_to(n2.d) == false if(content_features(n2).buildable_to == false
|| no_enough_privs) || no_enough_privs)
{ {
// Client probably has wrong data. // Client probably has wrong data.
@ -2736,14 +2736,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Create node data // Create node data
MaterialItem *mitem = (MaterialItem*)item; MaterialItem *mitem = (MaterialItem*)item;
MapNode n; MapNode n;
n.d = mitem->getMaterial(); n.setContent(mitem->getMaterial());
// Calculate direction for wall mounted stuff // Calculate direction for wall mounted stuff
if(content_features(n.d).wall_mounted) if(content_features(n).wall_mounted)
n.dir = packDir(p_under - p_over); n.param2 = packDir(p_under - p_over);
// Calculate the direction for furnaces and chests and stuff // 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 playerpos = player->getPosition();
v3f blockpos = intToFloat(p_over, BS) - playerpos; v3f blockpos = intToFloat(p_over, BS) - playerpos;

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

@ -93,7 +93,7 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
else else
{ {
c = 'X'; 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; u8 pr = m_data[m_area.index(x,y,z)].param2;
if(mode == VOXELPRINT_MATERIAL) if(mode == VOXELPRINT_MATERIAL)
{ {

@ -170,6 +170,9 @@ stuff = {}
starttime = time.time() starttime = time.time()
def data_is_air(d):
return (d == 254 or d == 126)
# Go through all sectors. # Go through all sectors.
for n in range(len(xlist)): for n in range(len(xlist)):
#if n > 500: #if n > 500:
@ -283,7 +286,7 @@ for n in range(len(xlist)):
for (x, z) in reversed(pixellist): for (x, z) in reversed(pixellist):
for y in reversed(range(16)): for y in reversed(range(16)):
datapos = x + y * 16 + z * 256 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): if(ord(mapdata[datapos]) == 2 or ord(mapdata[datapos]) == 9):
water[(x, z)] += 1 water[(x, z)] += 1
# Add dummy stuff for drawing sea without seabed # 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. # 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)]) stuff[(chunkxpos + x, chunkzpos + z)] = (chunkypos + y, ord(mapdata[datapos]), water[(x, z)])
break 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])) 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. # 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 (x, z) in reversed(pixellist):
for y in reversed(range(16)): for y in reversed(range(16)):
datapos = x + y * 16 + z * 256 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): if(ord(mapdata[datapos]) == 2 or ord(mapdata[datapos]) == 9):
water[(x, z)] += 1 water[(x, z)] += 1
# Add dummy stuff for drawing sea without seabed # 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. # 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)]) stuff[(chunkxpos + x, chunkzpos + z)] = (chunkypos + y, ord(mapdata[datapos]), water[(x, z)])
break 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])) 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. # After finding all the pixels in the sector, we can move on to the next sector without having to continue the Y axis.