{
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)
#include "inventory.h"
#include "content_mapnode.h"
#include "player.h"
+#include "mapnode.h" // For content_t
/*
items: actually *items[9]
*/
// CONTENT_IGNORE-terminated list
- u8 material_items[] = {
+ content_t material_items[] = {
CONTENT_TORCH,
CONTENT_COBBLE,
CONTENT_MUD,
CONTENT_IGNORE
};
- u8 *mip = material_items;
+ content_t *mip = material_items;
for(u16 i=0; i<PLAYER_INVENTORY_SIZE; i++)
{
if(*mip == CONTENT_IGNORE)
//#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;
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);
#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,
/*
Add torches to mesh
*/
- if(n.d == CONTENT_TORCH)
+ if(n.getContent() == CONTENT_TORCH)
{
video::SColor c(255,255,255,255);
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++)
{
/*
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::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++)
{
/*
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
// 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] = {
// 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)
+ else if(n2.getContent() == CONTENT_WATER)
level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
* node_water_level) * BS;
// 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;
}
/*
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)
/*
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)));
/*
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);
/*
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);
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;
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;
/*
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++)
{
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;*/
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},
+};
+
+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
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;
#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 is 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
+
+// 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
{
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;
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)
{
#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);
}
}
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);
}
}
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 &&
+ 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);
}
}
/*
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)
+ if(n_top.getContent() != CONTENT_AIR
+ && n_top.getContent() != CONTENT_IGNORE)
{
- n.d = CONTENT_MUD;
+ n.setContent(CONTENT_MUD);
m_map->addNodeWithEvent(p, n);
}
}
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)
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);
try
{
n = client->getNode(v3s16(x,y,z));
- if(content_pointable(n.d) == false)
+ if(content_pointable(n.getContent()) == false)
continue;
}
catch(InvalidPositionException &e)
/*
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;
}
}
}
- 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;
}
// Get digging properties for material and tool
- u8 material = n.d;
+ content_t material = n.getContent();
DiggingProperties prop =
getDiggingProperties(material, toolname);
is>>material;
u16 count;
is>>count;
- if(material > 255)
+ if(material > MAX_CONTENT)
throw SerializationError("Too large material number");
return new MaterialItem(material, count);
}
#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
class MaterialItem : public InventoryItem
{
public:
- MaterialItem(u8 content, u16 count):
+ MaterialItem(content_t content, u16 count):
InventoryItem(count)
{
m_content = content;
/*
Special methods
*/
- u8 getMaterial()
+ content_t getMaterial()
{
return m_content;
}
private:
- u8 m_content;
+ content_t m_content;
};
//TODO: Remove
+ This was left to be done by the old system and it sends only the\r
nearest ones.\r
\r
+Vim conversion regexpes for moving to extended content type storage:\r
+%s/\(\.\|->\)d \([!=]=\)/\1getContent() \2/g\r
+%s/content_features(\([^.]*\)\.d)/content_features(\1)/g\r
+%s/\(\.\|->\)d = \([^;]*\);/\1setContent(\2);/g\r
+%s/\(getNodeNoExNoEmerge([^)]*)\)\.d/\1.getContent()/g\r
+%s/\(getNodeNoExNoEmerge(.*)\)\.d/\1.getContent()/g\r
+%s/\.d;/.getContent();/g\r
+%s/\(content_liquid\|content_flowing_liquid\|make_liquid_flowing\|content_pointable\)(\([^.]*\).d)/\1(\2.getContent())/g\r
+Other things to note:\r
+- node.d = node.param0 (only in raw serialization; use getContent() otherwise)\r
+- node.param = node.param1\r
+- node.dir = node.param2\r
+- content_walkable(node.d) etc should be changed to\r
+ content_features(node).walkable etc\r
+- Also check for lines that store the result of getContent to a 8-bit\r
+ variable and fix them (result of getContent() must be stored in\r
+ content_t, which is 16-bit)\r
+\r
Old, wild and random suggestions that probably won't be done:\r
-------------------------------------------------------------\r
\r
\r
TODO: Merge bahamada's audio stuff (clean patch available)\r
\r
-TODO: Merge key configuration menu (no clean patch available)\r
+TODO: Move content_features to mapnode_content_features.{h,cpp} or so\r
\r
Making it more portable:\r
------------------------\r
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);
}*/
/*
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);
}
}
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
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);
}
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();
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--){
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
- if(content_liquid(n2.d))
+ if(content_liquid(n2.getContent()))
{
m_transforming_liquid.push_back(p2);
}
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,
*/
MapNode n;
- n.d = replace_material;
+ n.setContent(replace_material);
setNode(p, n);
for(s32 i=0; i<2; i++)
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
- if(content_liquid(n2.d))
+ if(content_liquid(n2.getContent()))
{
m_transforming_liquid.push_back(p2);
}
MapNode n0 = getNodeNoEx(p0);
// Don't deal with non-liquids
- if(content_liquid(n0.d) == false)
+ if(content_liquid(n0.getContent()) == false)
continue;
- bool is_source = !content_flowing_liquid(n0.d);
+ bool is_source = !content_flowing_liquid(n0.getContent());
u8 liquid_level = 8;
if(is_source == false)
liquid_level = n0.param2 & 0x0f;
// 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
v3s16 p2 = p0 + dirs_from[i];
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
if(n2_nonsource_c != nonsource_c)
{
" collide"<<std::endl;
continue;
}
- bool n2_is_source = !content_flowing_liquid(n2.d);
+ bool n2_is_source = !content_flowing_liquid(n2.getContent());
s8 n2_liquid_level = 8;
if(n2_is_source == false)
n2_liquid_level = n2.param2 & 0x07;
if(new_liquid_level_max == -1)
{
// Remove water alltoghether
- n0.d = CONTENT_AIR;
+ n0.setContent(CONTENT_AIR);
n0.param2 = 0;
setNode(p0, n0);
}
v3s16 p2 = p0 + dirs[i];
MapNode n2 = getNodeNoEx(p2);
- if(content_flowing_liquid(n2.d))
+ if(content_flowing_liquid(n2.getContent()))
{
m_transforming_liquid.push_back(p2);
}
}
// 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;
/*
MapNode n2 = getNodeNoEx(p2);
//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
if(n2_nonsource_c != nonsource_c)
{
" collide"<<std::endl;
continue;
}
- bool n2_is_source = !content_flowing_liquid(n2.d);
+ bool n2_is_source = !content_flowing_liquid(n2.getContent());
u8 n2_liquid_level = 8;
if(n2_is_source == false)
n2_liquid_level = n2.param2 & 0x07;
}
}
}
- 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;
setNode(p2, n2);
{
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<<")"
{
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);
}
}
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;
}
// 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 || n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
{
no_sunlight = true;
}
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;
}
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;
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;
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;
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);
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);
("MapBlock::deSerialize: invalid format");
for(u32 i=0; i<s.size(); i++)
{
- data[i].d = s[i];
+ data[i].param0 = s[i];
}
}
{
("MapBlock::deSerialize: invalid format");
for(u32 i=0; i<s.size(); i++)
{
- data[i].param = s[i];
+ data[i].param1 = s[i];
}
}
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
}
}
- return mn.d;
+ return mn.getContent();
}
v3s16 dirs8[8] = {
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++;
}
}
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)
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)
{
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);
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)
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)
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)
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)
{
}*/
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!
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
fits = false;
break;
}
- if(vmanip.m_data[vi].d == CONTENT_IGNORE)
+ if(vmanip.m_data[vi].getContent() == CONTENT_IGNORE)
{
fits = false;
break;
{
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;
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)
{
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);
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.
{
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);
}
{
}*/
- 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;
{
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);
}
{
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);
}
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)
{
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);
}
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);
}
{
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);
// 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);
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
}
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);
}
{
u32 i = data->vmanip->m_area.index(p);
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;
break;
{
u32 i = data->vmanip->m_area.index(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;
}
// Tree will be placed one higher
/*{
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
/*{
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
ContentFeatures::~ContentFeatures()
{
- /*if(translate_to)
- delete translate_to;*/
if(initial_metadata)
delete initial_metadata;
}
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.
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
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;
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;
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 != "")
{
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;
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)
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);
}
/*
/*
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.
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;
/*
// If the content is liquid, this is the flowing version of the liquid.
// If content is liquid, this is the same content.
- u8 liquid_alternative_flowing;
+ content_t liquid_alternative_flowing;
// Amount of light the node emits
u8 light_source;
void reset()
{
- //translate_to = NULL;
param_type = CPT_NONE;
inventory_texture = NULL;
is_ground_content = false;
/*
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.
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;
}
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;
}
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);
}
// 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;
}
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;
union
{
u8 param0;
- u8 d;
+ //u8 d;
};
/*
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)
*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;
+ }
}
/*
*/
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()
// 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();
{
// 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);
}
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);
// 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)
};
// For getting the default properties, set tool=""
-DiggingProperties getDiggingProperties(u8 material, const std::string &tool);
+DiggingProperties getDiggingProperties(u16 material, const std::string &tool);
#endif
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)
*/
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)
{
{
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)
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)
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
// 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;
// Get mineral
mineral = n.getMineral();
// Get material at position
- material = n.d;
+ material = n.getContent();
// If not yet cancelled
if(cannot_remove_node == false)
{
<<" 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.
// 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;
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);
}
};
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;
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
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);
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);
}
Parent fetch functions
*/
parent.position_valid = false;
- parent.node.d = 5;
+ parent.node.setContent(5);
MapNode n;
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);
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);*/
*/
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;
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);
}
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)
{
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:
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
# 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.
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
# 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.