X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fnodedef.cpp;h=4b2fe1643b1111fe5eb149193584dd060b0676df;hb=9733dd5b5e5516e18775665db132b2446492716c;hp=e38061e30d1b9231b6a850235db91b6ef400e9ad;hpb=fd845f27f5b3e3c6587c472be76235567a7b934d;p=minetest.git diff --git a/src/nodedef.cpp b/src/nodedef.cpp index e38061e30..4b2fe1643 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1,6 +1,6 @@ /* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "nameidmapping.h" #include "util/serialize.h" +//#include "profiler.h" // For TimeTaker /* NodeBox @@ -49,7 +50,7 @@ void NodeBox::serialize(std::ostream &os) const writeU8(os, 1); // version writeU8(os, type); - if(type == NODEBOX_FIXED) + if(type == NODEBOX_FIXED || type == NODEBOX_LEVELED) { writeU16(os, fixed.size()); for(std::vector::const_iterator @@ -81,7 +82,7 @@ void NodeBox::deSerialize(std::istream &is) type = (enum NodeBoxType)readU8(is); - if(type == NODEBOX_FIXED) + if(type == NODEBOX_FIXED || type == NODEBOX_LEVELED) { u16 fixed_count = readU16(is); while(fixed_count--) @@ -106,27 +107,32 @@ void NodeBox::deSerialize(std::istream &is) /* TileDef */ - -void TileDef::serialize(std::ostream &os) const + +void TileDef::serialize(std::ostream &os, u16 protocol_version) const { - writeU8(os, 0); // version + if(protocol_version >= 17) + writeU8(os, 1); + else + writeU8(os, 0); os<= 17) + writeU8(os, backface_culling); } void TileDef::deSerialize(std::istream &is) { int version = readU8(is); - if(version != 0) - throw SerializationError("unsupported TileDef version"); name = deSerializeString(is); animation.type = (TileAnimationType)readU8(is); animation.aspect_w = readU16(is); animation.aspect_h = readU16(is); animation.length = readF1000(is); + if(version >= 1) + backface_culling = readU8(is); } /* @@ -173,7 +179,7 @@ void ContentFeatures::reset() has_after_destruct = false; /* Actual data - + NOTE: Most of this is always overridden by the default values given in builtin.lua */ @@ -199,10 +205,14 @@ void ContentFeatures::reset() diggable = true; climbable = false; buildable_to = false; + rightclickable = true; + leveled = 0; liquid_type = LIQUID_NONE; liquid_alternative_flowing = ""; liquid_alternative_source = ""; liquid_viscosity = 0; + liquid_renewable = true; + drowning = true; light_source = 0; damage_per_second = 0; node_box = NodeBox(); @@ -214,9 +224,14 @@ void ContentFeatures::reset() sound_dug = SimpleSoundSpec(); } -void ContentFeatures::serialize(std::ostream &os) +void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) { - writeU8(os, 5); // version + if(protocol_version < 14){ + serializeOld(os, protocol_version); + return; + } + + writeU8(os, 6); // version os< &result) const { + //TimeTaker t("getIds", NULL, PRECISION_MICRO); if(name.substr(0,6) != "group:"){ content_t id = CONTENT_IGNORE; if(getId(name, id)) @@ -436,6 +467,20 @@ class CNodeDefManager: public IWritableNodeDefManager return; } std::string group = name.substr(6); + +#if 1 // Optimized version, takes less than 1 microsecond at -O1 + std::map::const_iterator + i = m_group_to_items.find(group); + if (i == m_group_to_items.end()) + return; + + const GroupItems &items = i->second; + for (GroupItems::const_iterator j = items.begin(); + j != items.end(); ++j) { + if ((*j).second != 0) + result.insert((*j).first); + } +#else // Old version, takes about ~150-200us at -O1 for(u16 id=0; id<=MAX_CONTENT; id++) { const ContentFeatures &f = m_content_features[id]; @@ -444,6 +489,8 @@ class CNodeDefManager: public IWritableNodeDefManager if(itemgroup_get(f.groups, group) != 0) result.insert(id); } +#endif + //printf("getIds: %dus\n", t.stop()); } virtual const ContentFeatures& get(const std::string &name) const { @@ -475,6 +522,21 @@ class CNodeDefManager: public IWritableNodeDefManager m_content_features[c] = def; if(def.name != "") addNameIdMapping(c, def.name); + + // Add this content to the list of all groups it belongs to + for (ItemGroupList::const_iterator i = def.groups.begin(); + i != def.groups.end(); ++i) { + std::string group_name = i->first; + + std::map::iterator + j = m_group_to_items.find(group_name); + if (j == m_group_to_items.end()) { + m_group_to_items[group_name].push_back(std::make_pair(c, i->second)); + } else { + GroupItems &items = j->second; + items.push_back(std::make_pair(c, i->second)); + } + } } virtual content_t set(const std::string &name, const ContentFeatures &def) @@ -526,20 +588,21 @@ class CNodeDefManager: public IWritableNodeDefManager bool new_style_water = g_settings->getBool("new_style_water"); bool new_style_leaves = g_settings->getBool("new_style_leaves"); bool opaque_water = g_settings->getBool("opaque_water"); - + for(u16 i=0; i<=MAX_CONTENT; i++) { ContentFeatures *f = &m_content_features[i]; - + // Figure out the actual tiles to use TileDef tiledef[6]; for(u32 j=0; j<6; j++) { tiledef[j] = f->tiledef[j]; if(tiledef[j].name == "") - tiledef[j].name = "unknown_block.png"; + tiledef[j].name = "unknown_node.png"; } + bool is_liquid = false; switch(f->drawtype){ default: case NDT_NORMAL: @@ -556,21 +619,25 @@ class CNodeDefManager: public IWritableNodeDefManager f->solidness = 0; } else { f->solidness = 1; - if(f->alpha == 255) - f->solidness = 2; f->backface_culling = false; } + is_liquid = true; break; case NDT_FLOWINGLIQUID: assert(f->liquid_type == LIQUID_FLOWING); f->solidness = 0; if(opaque_water) f->alpha = 255; + is_liquid = true; break; case NDT_GLASSLIKE: f->solidness = 0; f->visual_solidness = 1; break; + case NDT_GLASSLIKE_FRAMED: + f->solidness = 0; + f->visual_solidness = 1; + break; case NDT_ALLFACES: f->solidness = 0; f->visual_solidness = 1; @@ -588,9 +655,12 @@ class CNodeDefManager: public IWritableNodeDefManager } } break; + case NDT_PLANTLIKE: + f->solidness = 0; + f->backface_culling = false; + break; case NDT_TORCHLIKE: case NDT_SIGNLIKE: - case NDT_PLANTLIKE: case NDT_FENCELIKE: case NDT_RAILLIKE: case NDT_NODEBOX: @@ -598,16 +668,22 @@ class CNodeDefManager: public IWritableNodeDefManager break; } + u8 material_type; + if (is_liquid) + material_type = (f->alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; + else + material_type = (f->alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA; + // Tiles (fill in f->tiles[]) for(u16 j=0; j<6; j++){ // Texture - f->tiles[j].texture = tsrc->getTexture(tiledef[j].name); + f->tiles[j].texture = tsrc->getTexture( + tiledef[j].name, + &f->tiles[j].texture_id); // Alpha f->tiles[j].alpha = f->alpha; - if(f->alpha == 255) - f->tiles[j].material_type = MATERIAL_ALPHA_SIMPLE; - else - f->tiles[j].material_type = MATERIAL_ALPHA_VERTEX; + // Material type + f->tiles[j].material_type = material_type; // Material flags f->tiles[j].material_flags = 0; if(f->backface_culling) @@ -618,10 +694,9 @@ class CNodeDefManager: public IWritableNodeDefManager if(f->tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) { - // Get raw texture size to determine frame count by + // Get texture size to determine frame count by // aspect ratio - video::ITexture *t = tsrc->getTextureRaw(tiledef[j].name); - v2u32 size = t->getOriginalSize(); + v2u32 size = f->tiles[j].texture->getOriginalSize(); int frame_height = (float)size.X / (float)tiledef[j].animation.aspect_w * (float)tiledef[j].animation.aspect_h; @@ -644,14 +719,13 @@ class CNodeDefManager: public IWritableNodeDefManager // Special tiles (fill in f->special_tiles[]) for(u16 j=0; jspecial_tiles[j].texture = - tsrc->getTexture(f->tiledef_special[j].name); + f->special_tiles[j].texture = tsrc->getTexture( + f->tiledef_special[j].name, + &f->special_tiles[j].texture_id); // Alpha f->special_tiles[j].alpha = f->alpha; - if(f->alpha == 255) - f->special_tiles[j].material_type = MATERIAL_ALPHA_SIMPLE; - else - f->special_tiles[j].material_type = MATERIAL_ALPHA_VERTEX; + // Material type + f->special_tiles[j].material_type = material_type; // Material flags f->special_tiles[j].material_flags = 0; if(f->tiledef_special[j].backface_culling) @@ -662,10 +736,9 @@ class CNodeDefManager: public IWritableNodeDefManager if(f->special_tiles[j].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) { - // Get raw texture size to determine frame count by + // Get texture size to determine frame count by // aspect ratio - video::ITexture *t = tsrc->getTextureRaw(f->tiledef_special[j].name); - v2u32 size = t->getOriginalSize(); + v2u32 size = f->special_tiles[j].texture->getOriginalSize(); int frame_height = (float)size.X / (float)f->tiledef_special[j].animation.aspect_w * (float)f->tiledef_special[j].animation.aspect_h; @@ -688,7 +761,7 @@ class CNodeDefManager: public IWritableNodeDefManager } #endif } - void serialize(std::ostream &os) + void serialize(std::ostream &os, u16 protocol_version) { writeU8(os, 1); // version u16 count = 0; @@ -704,7 +777,7 @@ class CNodeDefManager: public IWritableNodeDefManager // Wrap it in a string to allow different lengths without // strict version incompatibilities std::ostringstream wrapper_os(std::ios::binary); - f->serialize(wrapper_os); + f->serialize(wrapper_os, protocol_version); os2< m_name_id_mapping_with_aliases; + // A mapping from groups to a list of content_ts (and their levels) + // that belong to it. Necessary for a direct lookup in getIds(). + // Note: Not serialized. + std::map m_group_to_items; }; IWritableNodeDefManager* createNodeDefManager() @@ -761,3 +838,122 @@ IWritableNodeDefManager* createNodeDefManager() return new CNodeDefManager(); } +/* + Serialization of old ContentFeatures formats +*/ + +void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version) +{ + if(protocol_version == 13) + { + writeU8(os, 5); // version + os<first); + writeS16(os, i->second); + } + writeU8(os, drawtype); + writeF1000(os, visual_scale); + writeU8(os, 6); + for(u32 i=0; i<6; i++) + tiledef[i].serialize(os, protocol_version); + writeU8(os, CF_SPECIAL_COUNT); + for(u32 i=0; i