From 64996422c00ddb70cfc8aee7da7b62485b8b0416 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 13 Nov 2011 10:57:55 +0200 Subject: [PATCH] Move ContentFeatures to mapnode_contentfeatures.{h,cpp} and clean stuff --- src/CMakeLists.txt | 1 + src/camera.cpp | 1 + src/collision.cpp | 1 + src/content_mapblock.cpp | 1 + src/content_mapnode.cpp | 11 + src/content_mapnode.h | 14 +- src/environment.cpp | 1 + src/game.cpp | 11 +- src/inventory.cpp | 8 + src/inventory.h | 5 +- src/main.cpp | 21 +- src/map.cpp | 3 +- src/mapblock.cpp | 1 + src/mapblock_mesh.cpp | 1 + src/mapgen.cpp | 1 + src/mapnode.cpp | 277 +++++++++---------- src/mapnode.h | 461 ++------------------------------ src/mapnode_contentfeatures.cpp | 145 ++++++++++ src/mapnode_contentfeatures.h | 338 +++++++++++++++++++++++ src/materials.cpp | 1 + src/player.cpp | 1 + src/server.cpp | 1 + src/servermain.cpp | 8 +- src/tile.cpp | 1 + 24 files changed, 697 insertions(+), 617 deletions(-) create mode 100644 src/mapnode_contentfeatures.cpp create mode 100644 src/mapnode_contentfeatures.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a511e6cc0..ca5a7756d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,6 +94,7 @@ configure_file( ) set(common_SRCS + mapnode_contentfeatures.cpp luaentity_common.cpp scriptapi.cpp script.cpp diff --git a/src/camera.cpp b/src/camera.cpp index a32336714..8188eaf61 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "settings.h" +#include "mapnode_contentfeatures.h" // For wield visualization Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): m_smgr(smgr), diff --git a/src/collision.cpp b/src/collision.cpp index 3d322cf0c..2380b1627 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "collision.h" #include "mapblock.h" #include "map.h" +#include "mapnode_contentfeatures.h" collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d, const core::aabbox3d &box_0, diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index b033e484c..4e9c65d41 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mineral.h" #include "mapblock_mesh.h" // For MapBlock_LightColor() #include "settings.h" +#include "mapnode_contentfeatures.h" #ifndef SERVER // Create a cuboid. diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index f10b941ba..a365f2ae9 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapnode.h" #include "content_nodemeta.h" #include "settings.h" +#include "mapnode_contentfeatures.h" #define WATER_ALPHA 160 @@ -101,8 +102,18 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version) return result; } +// See header for description void content_mapnode_init() { + if(g_texturesource == NULL) + dstream<<"INFO: Initial run of content_mapnode_init with " + "g_texturesource=NULL. If this segfaults, " + "there is a bug with something not checking for " + "the NULL value."<getBool("new_style_water"); bool new_style_leaves = g_settings->getBool("new_style_leaves"); diff --git a/src/content_mapnode.h b/src/content_mapnode.h index 4090f76f4..b58119724 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -22,10 +22,22 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapnode.h" +/* + Fills stuff to the global ContentFeatures lookup table. + + This accesses g_texturesource; if it is non-NULL, textures are set + for the nodes. + + Client first calls this with g_texturesource=NULL to run some + unit tests and stuff, then it runs this again with g_texturesource + defined to get the textures. + + Server only calls this once with g_texturesource=NULL. +*/ void content_mapnode_init(); +// Backwards compatibility for non-extended content types in v19 extern content_t trans_table_19[21][2]; - MapNode mapnode_translate_from_internal(MapNode n_from, u8 version); MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); diff --git a/src/environment.cpp b/src/environment.cpp index 29432bc5e..50c5a4b81 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "profiler.h" #include "scriptapi.h" +#include "mapnode_contentfeatures.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" diff --git a/src/game.cpp b/src/game.cpp index d666dbcdf..d7efbeae9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -43,13 +43,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "log.h" #include "filesys.h" - -/* - TODO: Move content-aware stuff to separate file by adding properties - and virtual interfaces -*/ +// Needed for some special cases for CONTENT_TORCH and CONTENT_SIGN_WALL +// TODO: A generic way for handling such should be created #include "content_mapnode.h" +// Needed for sign text input +// TODO: A generic way for handling such should be created #include "content_nodemeta.h" +// Needed for determining pointing to nodes +#include "mapnode_contentfeatures.h" /* Setting this to 1 enables a special camera mode that forces diff --git a/src/inventory.cpp b/src/inventory.cpp index c9ba9b4e5..ec1a81b18 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_sao.h" #include "player.h" #include "log.h" +#include "mapnode_contentfeatures.h" /* InventoryItem @@ -148,6 +149,13 @@ ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f MaterialItem */ +#ifndef SERVER +video::ITexture * MaterialItem::getImage() const +{ + return content_features(m_content).inventory_texture; +} +#endif + bool MaterialItem::isCookable() const { return item_material_is_cookable(m_content); diff --git a/src/inventory.h b/src/inventory.h index dc5b04ff7..c202d5533 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -151,10 +151,7 @@ public: return new MaterialItem(m_content, m_count); } #ifndef SERVER - video::ITexture * getImage() const - { - return content_features(m_content).inventory_texture; - } + video::ITexture * getImage() const; #endif std::string getText() { diff --git a/src/main.cpp b/src/main.cpp index b959d8c64..6b0cc1f83 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -365,11 +365,6 @@ SUGG: Restart irrlicht completely when coming back to main menu from game. TODO: Merge bahamada's audio stuff (clean patch available) -TODO: Move content_features to mapnode_content_features.{h,cpp} or so - -TODO: Fix item use() stuff; dropping a stack of cooked rats and eating - it gives 3 hearts and consumes all the rats. - Making it more portable: ------------------------ @@ -439,6 +434,8 @@ Doing currently: #include "settings.h" #include "profiler.h" #include "log.h" +#include "mapnode_contentfeatures.h" // For init_contentfeatures +#include "content_mapnode.h" // For content_mapnode_init // This makes textures ITextureSource *g_texturesource = NULL; @@ -1278,8 +1275,10 @@ int main(int argc, char *argv[]) These are needed for unit tests at least. */ - // Initial call with g_texturesource not set. - init_mapnode(); + // Initialize content feature table + init_contentfeatures(); + // Initialize mapnode content without textures (with g_texturesource=NULL) + content_mapnode_init(); // Must be called before g_texturesource is created // (for texture atlas making) init_mineral(); @@ -1482,7 +1481,8 @@ int main(int argc, char *argv[]) Preload some textures and stuff */ - init_mapnode(); // Second call with g_texturesource set + // Initialize mapnode content with textures (with g_texturesource!=NULL) + content_mapnode_init(); /* GUI stuff @@ -1658,7 +1658,10 @@ int main(int argc, char *argv[]) break; // Initialize mapnode again to enable changed graphics settings - init_mapnode(); + // Initialize content feature table + init_contentfeatures(); + // Initialize mapnode content with textures (with g_texturesource!=NULL) + content_mapnode_init(); /* Run game diff --git a/src/map.cpp b/src/map.cpp index f2ac3f618..858c08b63 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "log.h" #include "profiler.h" +#include "mapnode_contentfeatures.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -1773,7 +1774,7 @@ void Map::transformLiquids(core::map & modified_blocks) /* update the current node */ - bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK)); + //bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK)); if (content_features(new_node_content).liquid_type == LIQUID_FLOWING) { // set level to last 3 bits, flowing down bit to 4th bit n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK); diff --git a/src/mapblock.cpp b/src/mapblock.cpp index dd47c6ffc..85cd7e45e 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" #include "light.h" #include +#include "mapnode_contentfeatures.h" /* MapBlock diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 5a29fbe94..c81d5adc1 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_mapblock.h" #include "settings.h" #include "profiler.h" +#include "mapnode_contentfeatures.h" void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block) { diff --git a/src/mapgen.cpp b/src/mapgen.cpp index a74a91eeb..8fc568f36 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mineral.h" //#include "serverobject.h" #include "content_sao.h" +#include "mapnode_contentfeatures.h" namespace mapgen { diff --git a/src/mapnode.cpp b/src/mapnode.cpp index f81631999..3e44f5047 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -19,160 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include "mapnode.h" -#ifndef SERVER -#include "tile.h" -#endif #include "porting.h" #include #include "mineral.h" -// For g_settings -#include "main.h" -#include "content_mapnode.h" -#include "nodemetadata.h" - -ContentFeatures::~ContentFeatures() -{ - delete initial_metadata; -#ifndef SERVER - delete special_material; - delete special_atlas; -#endif -} - -#ifndef SERVER -void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha) -{ - used_texturenames[name] = true; - - if(g_texturesource) - { - tiles[i].texture = g_texturesource->getTexture(name); - } - - if(alpha != 255) - { - tiles[i].alpha = alpha; - tiles[i].material_type = MATERIAL_ALPHA_VERTEX; - } - - if(inventory_texture == NULL) - setInventoryTexture(name); -} - -void ContentFeatures::setInventoryTexture(std::string imgname) -{ - if(g_texturesource == NULL) - return; - - imgname += "^[forcesingle"; - - inventory_texture = g_texturesource->getTextureRaw(imgname); -} - -void ContentFeatures::setInventoryTextureCube(std::string top, - std::string left, std::string right) -{ - if(g_texturesource == NULL) - return; - - str_replace_char(top, '^', '&'); - str_replace_char(left, '^', '&'); - str_replace_char(right, '^', '&'); - - std::string imgname_full; - imgname_full += "[inventorycube{"; - imgname_full += top; - imgname_full += "{"; - imgname_full += left; - imgname_full += "{"; - imgname_full += right; - inventory_texture = g_texturesource->getTextureRaw(imgname_full); -} -#endif - -struct ContentFeatures g_content_features[MAX_CONTENT+1]; - -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. -*/ -void init_mapnode() -{ - if(g_texturesource == NULL) - { - dstream<<"INFO: Initial run of init_mapnode with " - "g_texturesource=NULL. If this segfaults, " - "there is a bug with something not checking for " - "the NULL value."<reset(); - - for(u16 j=0; j<6; j++) - f->tiles[j].material_type = initial_material_type; - } -#endif - - /* - Initially set every block to be shown as an unknown block. - Don't touch CONTENT_IGNORE or CONTENT_AIR. - */ - for(u16 i=0; isetAllTextures("unknown_block.png"); - f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; - } - - // Make CONTENT_IGNORE to not block the view when occlusion culling - content_features(CONTENT_IGNORE).solidness = 0; - - /* - Initialize mapnode content - */ - content_mapnode_init(); - -} +#include "main.h" // For g_settings +#include "mapnode_contentfeatures.h" +#include "content_mapnode.h" // For mapnode_translate_*_internal /* Nodes make a face if contents differ and solidness differs. @@ -248,6 +100,125 @@ v3s16 facedir_rotate(u8 facedir, v3s16 dir) return newdir; } +u8 packDir(v3s16 dir) +{ + u8 b = 0; + + if(dir.X > 0) + b |= (1<<0); + else if(dir.X < 0) + b |= (1<<1); + + if(dir.Y > 0) + b |= (1<<2); + else if(dir.Y < 0) + b |= (1<<3); + + if(dir.Z > 0) + b |= (1<<4); + else if(dir.Z < 0) + b |= (1<<5); + + return b; +} +v3s16 unpackDir(u8 b) +{ + v3s16 d(0,0,0); + + if(b & (1<<0)) + d.X = 1; + else if(b & (1<<1)) + d.X = -1; + + if(b & (1<<2)) + d.Y = 1; + else if(b & (1<<3)) + d.Y = -1; + + if(b & (1<<4)) + d.Z = 1; + else if(b & (1<<5)) + d.Z = -1; + + return d; +} + +/* + MapNode +*/ + +// These four are DEPRECATED. +bool MapNode::light_propagates() +{ + return light_propagates_content(getContent()); +} +bool MapNode::sunlight_propagates() +{ + return sunlight_propagates_content(getContent()); +} +u8 MapNode::solidness() +{ + return content_solidness(getContent()); +} +u8 MapNode::light_source() +{ + return content_features(*this).light_source; +} + +void MapNode::setLight(enum LightBank bank, u8 a_light) +{ + // If node doesn't contain light data, ignore this + if(content_features(*this).param_type != CPT_LIGHT) + return; + if(bank == LIGHTBANK_DAY) + { + param1 &= 0xf0; + param1 |= a_light & 0x0f; + } + else if(bank == LIGHTBANK_NIGHT) + { + param1 &= 0x0f; + param1 |= (a_light & 0x0f)<<4; + } + else + assert(0); +} + +u8 MapNode::getLight(enum LightBank bank) +{ + // Select the brightest of [light source, propagated light] + u8 light = 0; + if(content_features(*this).param_type == CPT_LIGHT) + { + if(bank == LIGHTBANK_DAY) + light = param1 & 0x0f; + else if(bank == LIGHTBANK_NIGHT) + light = (param1>>4)&0x0f; + else + assert(0); + } + if(light_source() > light) + light = light_source(); + return light; +} + +u8 MapNode::getLightBanksWithSource() +{ + // Select the brightest of [light source, propagated light] + u8 lightday = 0; + u8 lightnight = 0; + if(content_features(*this).param_type == CPT_LIGHT) + { + lightday = param1 & 0x0f; + lightnight = (param1>>4)&0x0f; + } + if(light_source() > lightday) + lightday = light_source(); + if(light_source() > lightnight) + lightnight = light_source(); + return (lightday&0x0f) | ((lightnight<<4)&0xf0); +} + #ifndef SERVER TileSpec MapNode::getTile(v3s16 dir) { @@ -424,8 +395,8 @@ void MapNode::deSerialize(u8 *source, u8 version) parameters: daynight_ratio: 0...1000 - n: getNodeParent(p) - n2: getNodeParent(p + face_dir) + n: getNode(p) (uses only the lighting value) + n2: getNode(p + face_dir) (uses only the lighting value) face_dir: axis oriented unit vector from p to p2 returns encoded light value. diff --git a/src/mapnode.h b/src/mapnode.h index 51bee0587..a93589c41 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -43,20 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc., typedef u16 content_t; #define MAX_CONTENT 0xfff -/* - Initializes all kind of stuff in here. - Many things depend on this. - - This accesses g_texturesource; if it is non-NULL, textures are set. - - Client first calls this with g_texturesource=NULL to run some - unit tests and stuff, then it runs this again with g_texturesource - defined to get the textures. - - Server only calls this once with g_texturesource=NULL. -*/ -void init_mapnode(); - /* Ignored node. @@ -66,7 +52,6 @@ void init_mapnode(); Doesn't create faces with anything and is considered being out-of-map in the game map. */ -//#define CONTENT_IGNORE 255 #define CONTENT_IGNORE 127 #define CONTENT_IGNORE_DEFAULT_PARAM 0 @@ -74,305 +59,8 @@ void init_mapnode(); The common material through which the player can walk and which is transparent to light */ -//#define CONTENT_AIR 254 #define CONTENT_AIR 126 -/* - Content feature list -*/ - -enum ContentParamType -{ - CPT_NONE, - CPT_LIGHT, - CPT_MINERAL, - // Direction for chests and furnaces and such - CPT_FACEDIR_SIMPLE -}; - -enum LiquidType -{ - LIQUID_NONE, - LIQUID_FLOWING, - LIQUID_SOURCE -}; - -struct MapNode; -class NodeMetadata; - -struct ContentFeatures -{ -#ifndef SERVER - /* - 0: up - 1: down - 2: right - 3: left - 4: back - 5: front - */ - TileSpec tiles[6]; - - video::ITexture *inventory_texture; - - // Used currently for flowing liquids - u8 vertex_alpha; - // Post effect color, drawn when the camera is inside the node. - video::SColor post_effect_color; - // Special irrlicht material, used sometimes - video::SMaterial *special_material; - video::SMaterial *special_material2; - AtlasPointer *special_atlas; -#endif - - // List of all block textures that have been used (value is dummy) - // Exists on server too for cleaner code in content_mapnode.cpp - core::map used_texturenames; - - // Type of MapNode::param1 - ContentParamType param_type; - // True for all ground-like things like stone and mud, false for eg. trees - bool is_ground_content; - bool light_propagates; - bool sunlight_propagates; - u8 solidness; // Used when choosing which face is drawn - u8 visual_solidness; // When solidness=0, this tells how it looks like - // 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 climb these - bool climbable; - // 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. 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; - // Whether this content type often contains mineral. - // Used for texture atlas creation. - // Currently only enabled for CONTENT_STONE. - bool often_contains_mineral; - - // Inventory item string as which the node appears in inventory when dug. - // Mineral overrides this. - std::string dug_item; - - // Extra dug item and its rarity - std::string extra_dug_item; - s32 extra_dug_item_rarity; - - // 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 liquid, this is the same content. - content_t liquid_alternative_flowing; - // If the content is liquid, this is the source version of the liquid. - content_t liquid_alternative_source; - // Viscosity for fluid flow, ranging from 1 to 7, with - // 1 giving almost instantaneous propagation and 7 being - // the slowest possible - u8 liquid_viscosity; - - // Amount of light the node emits - u8 light_source; - - // Digging properties for different tools - DiggingPropertiesList digging_properties; - - u32 damage_per_second; - - // NOTE: Move relevant properties to here from elsewhere - - void reset() - { -#ifndef SERVER - inventory_texture = NULL; - - vertex_alpha = 255; - post_effect_color = video::SColor(0, 0, 0, 0); - special_material = NULL; - special_material2 = NULL; - special_atlas = NULL; -#endif - param_type = CPT_NONE; - is_ground_content = false; - light_propagates = false; - sunlight_propagates = false; - solidness = 2; - visual_solidness = 0; - walkable = true; - pointable = true; - diggable = true; - climbable = false; - buildable_to = false; - liquid_type = LIQUID_NONE; - wall_mounted = false; - air_equivalent = false; - often_contains_mineral = false; - dug_item = ""; - initial_metadata = NULL; - liquid_alternative_flowing = CONTENT_IGNORE; - liquid_alternative_source = CONTENT_IGNORE; - liquid_viscosity = 0; - light_source = 0; - digging_properties.clear(); - damage_per_second = 0; - } - - ContentFeatures() - { - reset(); - } - - ~ContentFeatures(); - - /* - Quickhands for simple materials - */ - -#ifdef SERVER - void setTexture(u16 i, std::string name, u8 alpha=255) - {} - void setAllTextures(std::string name, u8 alpha=255) - {} -#else - void setTexture(u16 i, std::string name, u8 alpha=255); - - void setAllTextures(std::string name, u8 alpha=255) - { - for(u16 i=0; i<6; i++) - { - setTexture(i, name, alpha); - } - // Force inventory texture too - setInventoryTexture(name); - } -#endif - -#ifndef SERVER - void setTile(u16 i, const TileSpec &tile) - { - tiles[i] = tile; - } - void setAllTiles(const TileSpec &tile) - { - for(u16 i=0; i<6; i++) - { - setTile(i, tile); - } - } -#endif - -#ifdef SERVER - void setInventoryTexture(std::string imgname) - {} - void setInventoryTextureCube(std::string top, - std::string left, std::string right) - {} -#else - void setInventoryTexture(std::string imgname); - - void setInventoryTextureCube(std::string top, - std::string left, std::string right); -#endif -}; - -/* - Call this to access the ContentFeature list -*/ -ContentFeatures & content_features(content_t i); -ContentFeatures & content_features(MapNode &n); - -/* - Here is a bunch of DEPRECATED functions. -*/ - -/* - If true, the material allows light propagation and brightness is stored - in param. - NOTE: Don't use, use "content_features(m).whatever" instead -*/ -inline bool light_propagates_content(content_t m) -{ - return content_features(m).light_propagates; -} -/* - If true, the material allows lossless sunlight propagation. - 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(content_t m) -{ - return content_features(m).sunlight_propagates; -} -/* - On a node-node surface, the material of the node with higher solidness - is used for drawing. - 0: Invisible - 1: Transparent - 2: Opaque - NOTE: Don't use, use "content_features(m).whatever" instead -*/ -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(content_t m) -{ - return content_features(m).walkable; -} -// NOTE: Don't use, use "content_features(m).whatever" instead -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(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(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 content_t make_liquid_flowing(content_t m) -{ - 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(content_t m) -{ - return content_features(m).pointable; -} -// NOTE: Don't use, use "content_features(m).whatever" instead -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(content_t m) -{ - return content_features(m).buildable_to; -} - /* Nodes make a face if contents differ and solidness differs. Return value: @@ -384,50 +72,11 @@ inline bool content_buildable_to(content_t m) u8 face_contents(content_t m1, content_t m2, bool *equivalent); /* - Packs directions like (1,0,0), (1,-1,0) + Packs directions like (1,0,0), (1,-1,0) in six bits. + NOTE: This wastes way too much space for most purposes. */ -inline u8 packDir(v3s16 dir) -{ - u8 b = 0; - - if(dir.X > 0) - b |= (1<<0); - else if(dir.X < 0) - b |= (1<<1); - - if(dir.Y > 0) - b |= (1<<2); - else if(dir.Y < 0) - b |= (1<<3); - - if(dir.Z > 0) - b |= (1<<4); - else if(dir.Z < 0) - b |= (1<<5); - - return b; -} -inline v3s16 unpackDir(u8 b) -{ - v3s16 d(0,0,0); - - if(b & (1<<0)) - d.X = 1; - else if(b & (1<<1)) - d.X = -1; - - if(b & (1<<2)) - d.Y = 1; - else if(b & (1<<3)) - d.Y = -1; - - if(b & (1<<4)) - d.Z = 1; - else if(b & (1<<5)) - d.Z = -1; - - return d; -} +u8 packDir(v3s16 dir); +v3s16 unpackDir(u8 b); /* facedir: CPT_FACEDIR_SIMPLE param1 value @@ -467,11 +116,7 @@ struct MapNode 0x00-0x7f: Short content type 0x80-0xff: Long content type (param2>>4 makes up low bytes) */ - union - { - u8 param0; - //u8 d; - }; + u8 param0; /* Misc parameter. Initialized to 0. @@ -482,22 +127,14 @@ struct MapNode - Mineral content (should be removed from here) - Uhh... well, most blocks have light or nothing in here. */ - union - { - u8 param1; - //s8 param; - }; + u8 param1; /* 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 param2; MapNode(const MapNode & n) { @@ -506,10 +143,10 @@ struct MapNode MapNode(content_t content=CONTENT_AIR, u8 a_param1=0, u8 a_param2=0) { - //param0 = a_param0; param1 = a_param1; param2 = a_param2; - // Set after other params because this needs to override part of param2 + // Set content (param0 and (param2&0xf0)) after other params + // because this needs to override part of param2 setContent(content); } @@ -547,57 +184,14 @@ struct MapNode /* These four are DEPRECATED I guess. -c55 */ - bool light_propagates() - { - return light_propagates_content(getContent()); - } - bool sunlight_propagates() - { - return sunlight_propagates_content(getContent()); - } - u8 solidness() - { - return content_solidness(getContent()); - } - u8 light_source() - { - return content_features(*this).light_source; - } + bool light_propagates(); + bool sunlight_propagates(); + u8 solidness(); + u8 light_source(); - u8 getLightBanksWithSource() - { - // Select the brightest of [light source, propagated light] - u8 lightday = 0; - u8 lightnight = 0; - if(content_features(*this).param_type == CPT_LIGHT) - { - lightday = param1 & 0x0f; - lightnight = (param1>>4)&0x0f; - } - if(light_source() > lightday) - lightday = light_source(); - if(light_source() > lightnight) - lightnight = light_source(); - return (lightday&0x0f) | ((lightnight<<4)&0xf0); - } - - u8 getLight(enum LightBank bank) - { - // Select the brightest of [light source, propagated light] - u8 light = 0; - if(content_features(*this).param_type == CPT_LIGHT) - { - if(bank == LIGHTBANK_DAY) - light = param1 & 0x0f; - else if(bank == LIGHTBANK_NIGHT) - light = (param1>>4)&0x0f; - else - assert(0); - } - if(light_source() > light) - light = light_source(); - return light; - } + void setLight(enum LightBank bank, u8 a_light); + u8 getLight(enum LightBank bank); + u8 getLightBanksWithSource(); // 0 <= daylight_factor <= 1000 // 0 <= return value <= LIGHT_SUN @@ -625,25 +219,6 @@ struct MapNode return mix; }*/ - void setLight(enum LightBank bank, u8 a_light) - { - // If node doesn't contain light data, ignore this - if(content_features(*this).param_type != CPT_LIGHT) - return; - if(bank == LIGHTBANK_DAY) - { - param1 &= 0xf0; - param1 |= a_light & 0x0f; - } - else if(bank == LIGHTBANK_NIGHT) - { - param1 &= 0x0f; - param1 |= (a_light & 0x0f)<<4; - } - else - assert(0); - } - // In mapnode.cpp #ifndef SERVER /* @@ -681,8 +256,8 @@ struct MapNode parameters: daynight_ratio: 0...1000 - n: getNodeParent(p) - n2: getNodeParent(p + face_dir) + n: getNode(p) (uses only the lighting value) + n2: getNode(p + face_dir) (uses only the lighting value) face_dir: axis oriented unit vector from p to p2 returns encoded light value. diff --git a/src/mapnode_contentfeatures.cpp b/src/mapnode_contentfeatures.cpp new file mode 100644 index 000000000..aeab713c5 --- /dev/null +++ b/src/mapnode_contentfeatures.cpp @@ -0,0 +1,145 @@ +/* +Minetest-c55 +Copyright (C) 2010 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "mapnode_contentfeatures.h" + +#include "main.h" // For g_settings and g_texturesource +#include "nodemetadata.h" + +struct ContentFeatures g_content_features[MAX_CONTENT+1]; + +/* + Initialize content feature table. + + Must be called before accessing the table. +*/ +void init_contentfeatures() +{ +#ifndef SERVER + /* + Set initial material type to same in all tiles, so that the + same material can be used in more stuff. + This is set according to the leaves because they are the only + differing material to which all materials can be changed to + get this optimization. + */ + u8 initial_material_type = MATERIAL_ALPHA_SIMPLE; + /*if(new_style_leaves) + initial_material_type = MATERIAL_ALPHA_SIMPLE; + else + initial_material_type = MATERIAL_ALPHA_NONE;*/ + for(u16 i=0; ireset(); + + for(u16 j=0; j<6; j++) + f->tiles[j].material_type = initial_material_type; + } +#endif + + /* + Initially set every block to be shown as an unknown block. + Don't touch CONTENT_IGNORE or CONTENT_AIR. + */ + for(u16 i=0; isetAllTextures("unknown_block.png"); + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + } + + // Make CONTENT_IGNORE to not block the view when occlusion culling + content_features(CONTENT_IGNORE).solidness = 0; + +} + +ContentFeatures::~ContentFeatures() +{ + delete initial_metadata; +#ifndef SERVER + delete special_material; + delete special_atlas; +#endif +} + +#ifndef SERVER +void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha) +{ + used_texturenames[name] = true; + + if(g_texturesource) + { + tiles[i].texture = g_texturesource->getTexture(name); + } + + if(alpha != 255) + { + tiles[i].alpha = alpha; + tiles[i].material_type = MATERIAL_ALPHA_VERTEX; + } + + if(inventory_texture == NULL) + setInventoryTexture(name); +} + +void ContentFeatures::setInventoryTexture(std::string imgname) +{ + if(g_texturesource == NULL) + return; + + imgname += "^[forcesingle"; + + inventory_texture = g_texturesource->getTextureRaw(imgname); +} + +void ContentFeatures::setInventoryTextureCube(std::string top, + std::string left, std::string right) +{ + if(g_texturesource == NULL) + return; + + str_replace_char(top, '^', '&'); + str_replace_char(left, '^', '&'); + str_replace_char(right, '^', '&'); + + std::string imgname_full; + imgname_full += "[inventorycube{"; + imgname_full += top; + imgname_full += "{"; + imgname_full += left; + imgname_full += "{"; + imgname_full += right; + inventory_texture = g_texturesource->getTextureRaw(imgname_full); +} +#endif + +ContentFeatures & content_features(content_t i) +{ + return g_content_features[i]; +} +ContentFeatures & content_features(MapNode &n) +{ + return content_features(n.getContent()); +} + + diff --git a/src/mapnode_contentfeatures.h b/src/mapnode_contentfeatures.h new file mode 100644 index 000000000..86eceeab6 --- /dev/null +++ b/src/mapnode_contentfeatures.h @@ -0,0 +1,338 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef MAPNODE_CONTENTFEATURES_HEADER +#define MAPNODE_CONTENTFEATURES_HEADER + +#include "common_irrlicht.h" +#include +#include "mapnode.h" +#ifndef SERVER +#include "tile.h" +#endif + +/* + Content feature list + + Used for determining properties of MapNodes by content type without + storing such properties in the nodes itself. +*/ + +/* + Initialize content feature table. + + Must be called before accessing the table. +*/ +void init_contentfeatures(); + +enum ContentParamType +{ + CPT_NONE, + CPT_LIGHT, + CPT_MINERAL, + // Direction for chests and furnaces and such + CPT_FACEDIR_SIMPLE +}; + +enum LiquidType +{ + LIQUID_NONE, + LIQUID_FLOWING, + LIQUID_SOURCE +}; + +struct MapNode; +class NodeMetadata; + +struct ContentFeatures +{ +#ifndef SERVER + /* + 0: up + 1: down + 2: right + 3: left + 4: back + 5: front + */ + TileSpec tiles[6]; + + video::ITexture *inventory_texture; + + // Used currently for flowing liquids + u8 vertex_alpha; + // Post effect color, drawn when the camera is inside the node. + video::SColor post_effect_color; + // Special irrlicht material, used sometimes + video::SMaterial *special_material; + video::SMaterial *special_material2; + AtlasPointer *special_atlas; +#endif + + // List of all block textures that have been used (value is dummy) + // Exists on server too for cleaner code in content_mapnode.cpp + core::map used_texturenames; + + // Type of MapNode::param1 + ContentParamType param_type; + // True for all ground-like things like stone and mud, false for eg. trees + bool is_ground_content; + bool light_propagates; + bool sunlight_propagates; + u8 solidness; // Used when choosing which face is drawn + u8 visual_solidness; // When solidness=0, this tells how it looks like + // 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 climb these + bool climbable; + // 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. 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; + // Whether this content type often contains mineral. + // Used for texture atlas creation. + // Currently only enabled for CONTENT_STONE. + bool often_contains_mineral; + + // Inventory item string as which the node appears in inventory when dug. + // Mineral overrides this. + std::string dug_item; + + // Extra dug item and its rarity + std::string extra_dug_item; + s32 extra_dug_item_rarity; + + // 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 liquid, this is the same content. + content_t liquid_alternative_flowing; + // If the content is liquid, this is the source version of the liquid. + content_t liquid_alternative_source; + // Viscosity for fluid flow, ranging from 1 to 7, with + // 1 giving almost instantaneous propagation and 7 being + // the slowest possible + u8 liquid_viscosity; + + // Amount of light the node emits + u8 light_source; + + // Digging properties for different tools + DiggingPropertiesList digging_properties; + + u32 damage_per_second; + + // NOTE: Move relevant properties to here from elsewhere + + void reset() + { +#ifndef SERVER + inventory_texture = NULL; + + vertex_alpha = 255; + post_effect_color = video::SColor(0, 0, 0, 0); + special_material = NULL; + special_material2 = NULL; + special_atlas = NULL; +#endif + param_type = CPT_NONE; + is_ground_content = false; + light_propagates = false; + sunlight_propagates = false; + solidness = 2; + visual_solidness = 0; + walkable = true; + pointable = true; + diggable = true; + climbable = false; + buildable_to = false; + liquid_type = LIQUID_NONE; + wall_mounted = false; + air_equivalent = false; + often_contains_mineral = false; + dug_item = ""; + initial_metadata = NULL; + liquid_alternative_flowing = CONTENT_IGNORE; + liquid_alternative_source = CONTENT_IGNORE; + liquid_viscosity = 0; + light_source = 0; + digging_properties.clear(); + damage_per_second = 0; + } + + ContentFeatures() + { + reset(); + } + + ~ContentFeatures(); + + /* + Quickhands for simple materials + */ + +#ifdef SERVER + void setTexture(u16 i, std::string name, u8 alpha=255) + {} + void setAllTextures(std::string name, u8 alpha=255) + {} +#else + void setTexture(u16 i, std::string name, u8 alpha=255); + + void setAllTextures(std::string name, u8 alpha=255) + { + for(u16 i=0; i<6; i++) + { + setTexture(i, name, alpha); + } + // Force inventory texture too + setInventoryTexture(name); + } +#endif + +#ifndef SERVER + void setTile(u16 i, const TileSpec &tile) + { + tiles[i] = tile; + } + void setAllTiles(const TileSpec &tile) + { + for(u16 i=0; i<6; i++) + { + setTile(i, tile); + } + } +#endif + +#ifdef SERVER + void setInventoryTexture(std::string imgname) + {} + void setInventoryTextureCube(std::string top, + std::string left, std::string right) + {} +#else + void setInventoryTexture(std::string imgname); + + void setInventoryTextureCube(std::string top, + std::string left, std::string right); +#endif +}; + +/* + Call this to access the ContentFeature list +*/ +ContentFeatures & content_features(content_t i); +ContentFeatures & content_features(MapNode &n); + +/* + Here is a bunch of DEPRECATED functions. +*/ + +/* + If true, the material allows light propagation and brightness is stored + in param. + NOTE: Don't use, use "content_features(m).whatever" instead +*/ +inline bool light_propagates_content(content_t m) +{ + return content_features(m).light_propagates; +} +/* + If true, the material allows lossless sunlight propagation. + 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(content_t m) +{ + return content_features(m).sunlight_propagates; +} +/* + On a node-node surface, the material of the node with higher solidness + is used for drawing. + 0: Invisible + 1: Transparent + 2: Opaque + NOTE: Don't use, use "content_features(m).whatever" instead +*/ +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(content_t m) +{ + return content_features(m).walkable; +} +// NOTE: Don't use, use "content_features(m).whatever" instead +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(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(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 content_t make_liquid_flowing(content_t m) +{ + 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(content_t m) +{ + return content_features(m).pointable; +} +// NOTE: Don't use, use "content_features(m).whatever" instead +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(content_t m) +{ + return content_features(m).buildable_to; +} + + +#endif + diff --git a/src/materials.cpp b/src/materials.cpp index 24f300724..b3ee6e27a 100644 --- a/src/materials.cpp +++ b/src/materials.cpp @@ -1,5 +1,6 @@ #include "materials.h" #include "mapnode.h" +#include "mapnode_contentfeatures.h" // NOTE: DEPRECATED diff --git a/src/player.cpp b/src/player.cpp index f0a395f49..c8a3816e6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif #include "settings.h" +#include "mapnode_contentfeatures.h" Player::Player(): touching_ground(false), diff --git a/src/server.cpp b/src/server.cpp index 08a26adc6..95d3f9439 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "script.h" #include "scriptapi.h" +#include "mapnode_contentfeatures.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" diff --git a/src/servermain.cpp b/src/servermain.cpp index 73e1963c1..6bfcf2b75 100644 --- a/src/servermain.cpp +++ b/src/servermain.cpp @@ -74,6 +74,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "profiler.h" #include "log.h" +#include "mapnode_contentfeatures.h" // For init_contentfeatures +#include "content_mapnode.h" // For content_mapnode_init /* Settings. @@ -303,7 +305,11 @@ int main(int argc, char *argv[]) // Initialize stuff - init_mapnode(); + // Initialize content feature table + init_contentfeatures(); + // Initialize mapnode content without textures (with g_texturesource=NULL) + content_mapnode_init(); + init_mineral(); /* diff --git a/src/tile.cpp b/src/tile.cpp index f328ab766..32de8cda2 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "mapnode.h" // For texture atlas making #include "mineral.h" // For texture atlas making +#include "mapnode_contentfeatures.h" // For texture atlas making /* A cache from texture name to texture path