X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmapnode.h;h=33128049a2599692bf35212d671991e7b6401e2d;hb=7985d746f97ce1b37b6ca48a8a3e7ed70d02e4b0;hp=ba08a37daaeeec8c39f01b1b915def9540aaafcf;hpb=01c2b003e1efb839ad246eb939af7fa8336b9ad5;p=dragonfireclient.git diff --git a/src/mapnode.h b/src/mapnode.h index ba08a37da..33128049a 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -27,7 +27,21 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "exceptions.h" #include "serialization.h" #include "tile.h" -#include "iirrlichtwrapper.h" +#include "materials.h" + +/* + Naming scheme: + - Material = irrlicht's Material class + - Content = (u8) content of a node + - Tile = TileSpec at some side of a node of some content type +*/ + +/* + Ranges: + 0x000...0x07f: param2 is fully usable + 0x800...0xfff: param2 lower 4 bytes are free +*/ +typedef u16 content_t; /* Initializes all kind of stuff in here. @@ -43,13 +57,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ void init_mapnode(); -// Initializes g_content_inventory_texture_paths -void init_content_inventory_texture_paths(); - - -// NOTE: This is not used appropriately everywhere. -#define MATERIALS_COUNT 256 - /* Ignored node. @@ -59,43 +66,16 @@ void init_content_inventory_texture_paths(); Doesn't create faces with anything and is considered being out-of-map in the game map. */ -#define CONTENT_IGNORE 255 +//#define CONTENT_IGNORE 255 +#define CONTENT_IGNORE 127 #define CONTENT_IGNORE_DEFAULT_PARAM 0 /* The common material through which the player can walk and which is transparent to light */ -#define CONTENT_AIR 254 - -/* - Suggested materials: - - Gravel - - Sand - - New naming scheme: - - Material = irrlicht's Material class - - Content = (u8) content of a node - - Tile = (u16) Material ID at some side of a node -*/ - -#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_FURNACE 14 -#define CONTENT_SIGN_WALL 15 +//#define CONTENT_AIR 254 +#define CONTENT_AIR 126 /* Content feature list @@ -105,7 +85,9 @@ enum ContentParamType { CPT_NONE, CPT_LIGHT, - CPT_MINERAL + CPT_MINERAL, + // Direction for chests and furnaces and such + CPT_FACEDIR_SIMPLE }; enum LiquidType @@ -116,11 +98,12 @@ enum LiquidType }; class MapNode; +class NodeMetadata; struct ContentFeatures { // If non-NULL, content is translated to this when deserialized - MapNode *translate_to; + //MapNode *translate_to; // Type of MapNode::param ContentParamType param_type; @@ -135,34 +118,54 @@ struct ContentFeatures */ TileSpec tiles[6]; - // TODO: Somehow specify inventory image - //std::string inventory_image_path; - //TextureSpec inventory_texture; - //u32 inventory_texture_id; video::ITexture *inventory_texture; - bool is_ground_content; //TODO: Remove, use walkable instead + bool is_ground_content; bool light_propagates; bool sunlight_propagates; u8 solidness; // Used when choosing which face is drawn + // This is used for collision detection. + // Also for general solidness queries. bool walkable; + // Player can point to these bool pointable; + // Player can dig these bool diggable; + // Player can build on these bool buildable_to; + // Whether the node has no liquid, source liquid or flowing liquid enum LiquidType liquid_type; - // If true, param2 is set to direction when placed + // If true, param2 is set to direction when placed. Used for torches. // NOTE: the direction format is quite inefficient and should be changed bool wall_mounted; + // If true, node is equivalent to air. Torches are, air is. Water is not. + // Is used for example to check whether a mud block can have grass on. + bool air_equivalent; // Inventory item string as which the node appears in inventory when dug. // Mineral overrides this. std::string dug_item; + + // Initial metadata is cloned from this + NodeMetadata *initial_metadata; + + // If the content is liquid, this is the flowing version of the liquid. + // If content is flowing liquid, this is the same content. + u8 liquid_alternative_flowing; + // If the content is liquid, this is the source version of the liquid. + u8 liquid_alternative_source; + + // Amount of light the node emits + u8 light_source; + + // Digging properties for different tools + DiggingPropertiesList digging_properties; + + // NOTE: Move relevant properties to here from elsewhere - //TODO: Move more properties here - - ContentFeatures() + void reset() { - translate_to = NULL; + //translate_to = NULL; param_type = CPT_NONE; inventory_texture = NULL; is_ground_content = false; @@ -175,7 +178,17 @@ struct ContentFeatures buildable_to = false; liquid_type = LIQUID_NONE; wall_mounted = false; + air_equivalent = false; dug_item = ""; + initial_metadata = NULL; + liquid_alternative_flowing = CONTENT_IGNORE; + light_source = 0; + digging_properties.clear(); + } + + ContentFeatures() + { + reset(); } ~ContentFeatures(); @@ -192,6 +205,8 @@ struct ContentFeatures { setTexture(i, name, alpha); } + // Force inventory texture too + setInventoryTexture(name); } void setTile(u16 i, const TileSpec &tile) @@ -217,6 +232,11 @@ struct ContentFeatures */ ContentFeatures & content_features(u8 i); + +/* + Here is a bunch of DEPRECATED functions. +*/ + /* If true, the material allows light propagation and brightness is stored in param. @@ -225,9 +245,7 @@ ContentFeatures & content_features(u8 i); inline bool light_propagates_content(u8 m) { return content_features(m).light_propagates; - //return (m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER || m == CONTENT_WATERSOURCE); } - /* If true, the material allows lossless sunlight propagation. NOTE: It doesn't seem to go through torches regardlessly of this @@ -236,9 +254,7 @@ inline bool light_propagates_content(u8 m) inline bool sunlight_propagates_content(u8 m) { return content_features(m).sunlight_propagates; - //return (m == CONTENT_AIR || m == CONTENT_TORCH); } - /* On a node-node surface, the material of the node with higher solidness is used for drawing. @@ -250,83 +266,54 @@ inline bool sunlight_propagates_content(u8 m) inline u8 content_solidness(u8 m) { return content_features(m).solidness; - /*// As of now, every pseudo node like torches are added to this - if(m == CONTENT_AIR || m == CONTENT_TORCH || m == CONTENT_WATER) - return 0; - if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE) - return 1; - return 2;*/ } - // Objects collide with walkable contents // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_walkable(u8 m) { return content_features(m).walkable; - //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE && m != CONTENT_TORCH); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_liquid(u8 m) { return content_features(m).liquid_type != LIQUID_NONE; - //return (m == CONTENT_WATER || m == CONTENT_WATERSOURCE); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_flowing_liquid(u8 m) { return content_features(m).liquid_type == LIQUID_FLOWING; - //return (m == CONTENT_WATER); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_liquid_source(u8 m) { return content_features(m).liquid_type == LIQUID_SOURCE; - //return (m == CONTENT_WATERSOURCE); } - // 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) { - if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE) - return CONTENT_WATER; - assert(0); + u8 c = content_features(m).liquid_alternative_flowing; + assert(c != CONTENT_IGNORE); + return c; } - // 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) { return content_features(m).pointable; - //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_diggable(u8 m) { return content_features(m).diggable; - //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_buildable_to(u8 m) { return content_features(m).buildable_to; - //return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE); } -/* - Returns true for contents that form the base ground that - follows the main heightmap -*/ -/*inline bool is_ground_content(u8 m) -{ - return content_features(m).is_ground_content; -}*/ - /* Nodes make a face if contents differ and solidness differs. Return value: @@ -404,36 +391,64 @@ inline v3s16 unpackDir(u8 b) return d; } +/* + facedir: CPT_FACEDIR_SIMPLE param1 value + dir: The face for which stuff is wanted + return value: The face from which the stuff is actually found +*/ +v3s16 facedir_rotate(u8 facedir, v3s16 dir); + enum LightBank { LIGHTBANK_DAY, LIGHTBANK_NIGHT }; +/* + Masks for MapNode.param2 of flowing liquids + */ +#define LIQUID_LEVEL_MASK 0x07 +#define LIQUID_FLOW_DOWN_MASK 0x08 + /* This is the stuff what the whole world consists of. */ + struct MapNode { - // Content - u8 d; + /* + Main content + 0x00-0x7f: Short content type + 0x80-0xff: Long content type (param2>>4 makes up low bytes) + */ + union + { + u8 param0; + u8 d; + }; /* Misc parameter. Initialized to 0. - For light_propagates() blocks, this is light intensity, stored logarithmically from 0 to LIGHT_MAX. Sunlight is LIGHT_SUN, which is LIGHT_MAX+1. - - Contains 2 values, day- and night lighting. Each takes 4 bits. + - Contains 2 values, day- and night lighting. Each takes 4 bits. + - Mineral content (should be removed from here) + - Uhh... well, most blocks have light or nothing in here. */ - s8 param; + union + { + u8 param1; + s8 param; + }; + /* + The second parameter. Initialized to 0. + E.g. direction for torches and flowing water. + */ union { - /* - The second parameter. Initialized to 0. - Direction for torches and flowing water. - */ u8 param2; u8 dir; }; @@ -450,45 +465,41 @@ struct MapNode param2 = a_param2; } - /*MapNode & operator=(const MapNode &other) - { - d = other.d; - param = other.param; - param2 = other.param2; - return *this; - }*/ - bool operator==(const MapNode &other) { return (d == other.d && param == other.param && param2 == other.param2); } - + + // To be used everywhere + content_t getContent() + { + return d; + } + void setContent(content_t c) + { + d = c; + } + + /* + These four are DEPRECATED I guess. -c55 + */ bool light_propagates() { return light_propagates_content(d); } - bool sunlight_propagates() { return sunlight_propagates_content(d); } - u8 solidness() { return content_solidness(d); } - u8 light_source() { - /* - Note that a block that isn't light_propagates() can be a light source. - */ - if(d == CONTENT_TORCH) - return LIGHT_MAX; - - return 0; + return content_features(d).light_source; } u8 getLightBanksWithSource() @@ -496,7 +507,7 @@ struct MapNode // Select the brightest of [light source, propagated light] u8 lightday = 0; u8 lightnight = 0; - if(light_propagates()) + if(content_features(d).param_type == CPT_LIGHT) { lightday = param & 0x0f; lightnight = (param>>4)&0x0f; @@ -508,16 +519,11 @@ struct MapNode return (lightday&0x0f) | ((lightnight<<4)&0xf0); } - void setLightBanks(u8 a_light) - { - param = a_light; - } - u8 getLight(enum LightBank bank) { // Select the brightest of [light source, propagated light] u8 light = 0; - if(light_propagates()) + if(content_features(d).param_type == CPT_LIGHT) { if(bank == LIGHTBANK_DAY) light = param & 0x0f; @@ -559,8 +565,8 @@ struct MapNode void setLight(enum LightBank bank, u8 a_light) { - // If not transparent, can't set light - if(light_propagates() == false) + // If node doesn't contain light data, ignore this + if(content_features(d).param_type != CPT_LIGHT) return; if(bank == LIGHTBANK_DAY) { @@ -577,92 +583,48 @@ struct MapNode } // In mapnode.cpp + /* + Get tile of a face of the node. + dir: direction of face + Returns: TileSpec. Can contain miscellaneous texture coordinates, + which must be obeyed so that the texture atlas can be used. + */ TileSpec getTile(v3s16 dir); - + + /* + Gets mineral content of node, if there is any. + MINERAL_NONE if doesn't contain or isn't able to contain mineral. + */ u8 getMineral(); - + /* - These serialization functions are used when informing client - of a single node add + Serialization functions */ - static u32 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 serialize(u8 *dest, u8 version) - { - if(!ser_ver_supported(version)) - throw VersionMismatchException("ERROR: MapNode format not supported"); - - if(version == 0) - { - dest[0] = d; - } - else if(version <= 9) - { - dest[0] = d; - dest[1] = param; - } - else - { - dest[0] = d; - dest[1] = param; - dest[2] = param2; - } - } - void deSerialize(u8 *source, u8 version) - { - if(!ser_ver_supported(version)) - throw VersionMismatchException("ERROR: MapNode format not supported"); - - if(version == 0) - { - d = source[0]; - } - else if(version == 1) - { - d = source[0]; - // This version doesn't support saved lighting - if(light_propagates() || light_source() > 0) - param = 0; - else - param = source[1]; - } - else if(version <= 9) - { - d = source[0]; - param = source[1]; - } - else - { - d = source[0]; - param = source[1]; - param2 = source[2]; - } - - // Translate deprecated stuff - // NOTE: This doesn't get used because MapBlock handles node - // parameters directly - MapNode *translate_to = content_features(d).translate_to; - if(translate_to) - { - dstream<<"MapNode: WARNING: Translating "<d<