X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmapnode.cpp;h=c9f85c303ddd35698f795c7e365972b3dd60a85d;hb=24a662705cb73f8a5630114654c38a0e1328b9ec;hp=2ca4ade7a75e889f33e0b25ce7fb8e18b444c876;hpb=467f43d47ccff77d2f35d0807e9d66181694daec;p=dragonfireclient.git diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 2ca4ade7a..c9f85c303 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -25,11 +25,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mineral.h" // For g_settings #include "main.h" +#include "content_mapnode.h" +#include "nodemetadata.h" ContentFeatures::~ContentFeatures() { - if(translate_to) - delete translate_to; + if(initial_metadata) + delete initial_metadata; } void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha) @@ -79,12 +81,16 @@ void ContentFeatures::setInventoryTextureCube(std::string top, inventory_texture = g_texturesource->getTextureRaw(imgname_full); } -struct ContentFeatures g_content_features[256]; +struct ContentFeatures g_content_features[MAX_CONTENT+1]; -ContentFeatures & content_features(u8 i) +ContentFeatures & content_features(content_t i) { return g_content_features[i]; } +ContentFeatures & content_features(MapNode &n) +{ + return content_features(n.getContent()); +} /* See mapnode.h for description. @@ -104,9 +110,9 @@ void init_mapnode() "g_texturesource!=NULL"<reset(); + for(u16 j=0; j<6; j++) f->tiles[j].material_type = initial_material_type; } - - u8 i; - ContentFeatures *f = NULL; - - i = CONTENT_STONE; - f = &g_content_features[i]; - f->setAllTextures("stone.png"); - f->setInventoryTextureCube("stone.png", "stone.png", "stone.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_GRASS; - f = &g_content_features[i]; - f->setAllTextures("mud.png^grass_side.png"); - f->setTexture(0, "grass.png"); - f->setTexture(1, "mud.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1"; - - i = CONTENT_GRASS_FOOTSTEPS; - f = &g_content_features[i]; - f->setAllTextures("mud.png^grass_side.png"); - f->setTexture(0, "grass_footsteps.png"); - f->setTexture(1, "mud.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1"; - - i = CONTENT_MUD; - f = &g_content_features[i]; - f->setAllTextures("mud.png"); - f->setInventoryTextureCube("mud.png", "mud.png", "mud.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_SAND; - f = &g_content_features[i]; - f->setAllTextures("sand.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_TREE; - f = &g_content_features[i]; - f->setAllTextures("tree.png"); - f->setTexture(0, "tree_top.png"); - f->setTexture(1, "tree_top.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_LEAVES; - f = &g_content_features[i]; - f->light_propagates = true; - //f->param_type = CPT_MINERAL; - f->param_type = CPT_LIGHT; - f->is_ground_content = true; - if(new_style_leaves) - { - f->solidness = 0; // drawn separately, makes no faces - f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png"); - } - else - { - f->setAllTextures("[noalpha:leaves.png"); - } - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_COALSTONE; - f = &g_content_features[i]; - //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL); - f->setAllTextures("stone.png^mineral_coal.png"); - f->is_ground_content = true; - - i = CONTENT_WOOD; - f = &g_content_features[i]; - f->setAllTextures("wood.png"); - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_MESE; - f = &g_content_features[i]; - f->setAllTextures("mese.png"); - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_CLOUD; - f = &g_content_features[i]; - f->setAllTextures("cloud.png"); - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_AIR; - f = &g_content_features[i]; - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->sunlight_propagates = true; - f->solidness = 0; - f->walkable = false; - f->pointable = false; - f->diggable = false; - f->buildable_to = true; - - i = CONTENT_WATER; - f = &g_content_features[i]; - f->setInventoryTextureCube("water.png", "water.png", "water.png"); - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->solidness = 0; // Drawn separately, makes no faces - f->walkable = false; - f->pointable = false; - f->diggable = false; - f->buildable_to = true; - f->liquid_type = LIQUID_FLOWING; - - i = CONTENT_WATERSOURCE; - f = &g_content_features[i]; - f->setInventoryTexture("water.png"); - if(new_style_water) + + /* + Initially set every block to be shown as an unknown block. + Don't touch CONTENT_IGNORE or CONTENT_AIR. + */ + for(u16 i=0; isolidness = 0; // drawn separately, makes no faces + if(i == CONTENT_IGNORE || i == CONTENT_AIR) + continue; + ContentFeatures *f = &g_content_features[i]; + f->setAllTextures("unknown_block.png"); + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; } - else // old style - { - f->solidness = 1; - TileSpec t; - if(g_texturesource) - t.texture = g_texturesource->getTexture("water.png"); - - t.alpha = WATER_ALPHA; - t.material_type = MATERIAL_ALPHA_VERTEX; - t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; - f->setAllTiles(t); - } - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->walkable = false; - f->pointable = false; - f->diggable = false; - f->buildable_to = true; - f->liquid_type = LIQUID_SOURCE; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_TORCH; - f = &g_content_features[i]; - f->setInventoryTexture("torch_on_floor.png"); - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->solidness = 0; // drawn separately, makes no faces - f->walkable = false; - f->wall_mounted = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + /* + Initialize mapnode content + */ + content_mapnode_init(); } +v3s16 facedir_rotate(u8 facedir, v3s16 dir) +{ + /* + Face 2 (normally Z-) direction: + facedir=0: Z- + facedir=1: X- + facedir=2: Z+ + facedir=3: X+ + */ + v3s16 newdir; + if(facedir==0) // Same + newdir = v3s16(dir.X, dir.Y, dir.Z); + else if(facedir == 1) // Face is taken from rotXZccv(-90) + newdir = v3s16(-dir.Z, dir.Y, dir.X); + else if(facedir == 2) // Face is taken from rotXZccv(180) + newdir = v3s16(-dir.X, dir.Y, -dir.Z); + else if(facedir == 3) // Face is taken from rotXZccv(90) + newdir = v3s16(dir.Z, dir.Y, -dir.X); + else + newdir = dir; + return newdir; +} + TileSpec MapNode::getTile(v3s16 dir) { + if(content_features(*this).param_type == CPT_FACEDIR_SIMPLE) + dir = facedir_rotate(param1, dir); + TileSpec spec; s32 dir_i = -1; @@ -312,16 +209,16 @@ TileSpec MapNode::getTile(v3s16 dir) if(dir_i == -1) // Non-directional - spec = content_features(d).tiles[0]; + spec = content_features(*this).tiles[0]; else - spec = content_features(d).tiles[dir_i]; + spec = content_features(*this).tiles[dir_i]; /* If it contains some mineral, change texture id */ - if(content_features(d).param_type == CPT_MINERAL && g_texturesource) + if(content_features(*this).param_type == CPT_MINERAL && g_texturesource) { - u8 mineral = param & 0x1f; + u8 mineral = getMineral(); std::string mineral_texture_name = mineral_block_texture(mineral); if(mineral_texture_name != "") { @@ -340,24 +237,164 @@ TileSpec MapNode::getTile(v3s16 dir) u8 MapNode::getMineral() { - if(content_features(d).param_type == CPT_MINERAL) + if(content_features(*this).param_type == CPT_MINERAL) { - return param & 0x1f; + return param1 & 0x0f; } return MINERAL_NONE; } -// Pointers to c_str()s g_content_features[i].inventory_image_path -//const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0}; +u32 MapNode::serializedLength(u8 version) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + if(version == 0) + return 1; + else if(version <= 9) + return 2; + else + return 3; +} +void MapNode::serialize(u8 *dest, u8 version) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + // Translate to wanted version + MapNode n_foreign = mapnode_translate_from_internal(*this, version); -void init_content_inventory_texture_paths() + 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_param0 == CONTENT_IGNORE) + actual_param0 = 255; + else if(actual_param0 == CONTENT_AIR) + actual_param0 = 254; + } + + if(version == 0) + { + dest[0] = actual_param0; + } + else if(version <= 9) + { + dest[0] = actual_param0; + dest[1] = n_foreign.param1; + } + else + { + dest[0] = actual_param0; + dest[1] = n_foreign.param1; + dest[2] = n_foreign.param2; + } +} +void MapNode::deSerialize(u8 *source, u8 version) +{ + if(!ser_ver_supported(version)) + throw VersionMismatchException("ERROR: MapNode format not supported"); + + if(version == 0) + { + param0 = source[0]; + } + else if(version == 1) + { + param0 = source[0]; + // This version doesn't support saved lighting + if(light_propagates() || light_source() > 0) + param1 = 0; + else + param1 = source[1]; + } + else if(version <= 9) + { + param0 = source[0]; + param1 = source[1]; + } + else + { + param0 = source[0]; + param1 = source[1]; + param2 = source[2]; + } + + // Convert special values from old version to new + if(version <= 18) + { + // In these versions, CONTENT_IGNORE and CONTENT_AIR + // are 255 and 254 + 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(param0 == 255) + param0 = CONTENT_IGNORE; + else if(param0 == 254) + param0 = CONTENT_AIR; + } + + // Translate to our known version + *this = mapnode_translate_to_internal(*this, version); +} + +/* + Gets lighting value at face of node + + Parameters must consist of air and !air. + Order doesn't matter. + + If either of the nodes doesn't exist, light is 0. + + parameters: + daynight_ratio: 0...1000 + n: getNodeParent(p) + n2: getNodeParent(p + face_dir) + face_dir: axis oriented unit vector from p to p2 + + returns encoded light value. +*/ +u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, + v3s16 face_dir) { - dstream<<"DEPRECATED "<<__FUNCTION_NAME< l2) + light = l1; + else + light = l2; + + // Make some nice difference to different sides + + // This makes light come from a corner + /*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1) + light = diminish_light(diminish_light(light)); + else if(face_dir.X == -1 || face_dir.Z == -1) + light = diminish_light(light);*/ + + // All neighboring faces have different shade (like in minecraft) + if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1) + light = diminish_light(diminish_light(light)); + else if(face_dir.Z == 1 || face_dir.Z == -1) + light = diminish_light(light); + + return light; + } + catch(InvalidPositionException &e) { - g_content_inventory_texture_paths[i] = - g_content_features[i].inventory_image_path.c_str(); - }*/ + return 0; + } } +