)
set(common_SRCS
+ mapnode_contentfeatures.cpp
luaentity_common.cpp
scriptapi.cpp
script.cpp
#include <cmath>
#include <SAnimatedMesh.h>
#include "settings.h"
+#include "mapnode_contentfeatures.h" // For wield visualization
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr),
#include "collision.h"
#include "mapblock.h"
#include "map.h"
+#include "mapnode_contentfeatures.h"
collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
const core::aabbox3d<f32> &box_0,
#include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor()
#include "settings.h"
+#include "mapnode_contentfeatures.h"
#ifndef SERVER
// Create a cuboid.
#include "mapnode.h"
#include "content_nodemeta.h"
#include "settings.h"
+#include "mapnode_contentfeatures.h"
#define WATER_ALPHA 160
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."<<std::endl;
+ else
+ dstream<<"INFO: Full run of content_mapnode_init with "
+ "g_texturesource!=NULL"<<std::endl;
+
// Read some settings
bool new_style_water = g_settings->getBool("new_style_water");
bool new_style_leaves = g_settings->getBool("new_style_leaves");
#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);
#include "log.h"
#include "profiler.h"
#include "scriptapi.h"
+#include "mapnode_contentfeatures.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
#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
#include "content_sao.h"
#include "player.h"
#include "log.h"
+#include "mapnode_contentfeatures.h"
/*
InventoryItem
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);
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()
{
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:
------------------------
#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;
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();
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
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
#include "settings.h"
#include "log.h"
#include "profiler.h"
+#include "mapnode_contentfeatures.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
/*
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);
#include "main.h"
#include "light.h"
#include <sstream>
+#include "mapnode_contentfeatures.h"
/*
MapBlock
#include "content_mapblock.h"
#include "settings.h"
#include "profiler.h"
+#include "mapnode_contentfeatures.h"
void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
{
#include "mineral.h"
//#include "serverobject.h"
#include "content_sao.h"
+#include "mapnode_contentfeatures.h"
namespace mapgen
{
#include "common_irrlicht.h"
#include "mapnode.h"
-#ifndef SERVER
-#include "tile.h"
-#endif
#include "porting.h"
#include <string>
#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."<<std::endl;
- }
- else
- {
- dstream<<"INFO: Full run of init_mapnode with "
- "g_texturesource!=NULL"<<std::endl;
- }
-
- /*// Read some settings
- bool new_style_water = g_settings.getBool("new_style_water");
- bool new_style_leaves = g_settings.getBool("new_style_leaves");*/
-
- /*
- Initialize content feature table
- */
-
-#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; i<MAX_CONTENT+1; i++)
- {
- ContentFeatures *f = &g_content_features[i];
- // Re-initialize
- f->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; i<MAX_CONTENT+1; i++)
- {
- if(i == CONTENT_IGNORE || i == CONTENT_AIR)
- continue;
- ContentFeatures *f = &g_content_features[i];
- f->setAllTextures("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.
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)
{
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.
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.
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
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<std::string, bool> 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:
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
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.
- 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)
{
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);
}
/*
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;
- }
-
- 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;
- }
+ bool light_propagates();
+ bool sunlight_propagates();
+ u8 solidness();
+ u8 light_source();
+
+ void setLight(enum LightBank bank, u8 a_light);
+ u8 getLight(enum LightBank bank);
+ u8 getLightBanksWithSource();
// 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN
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
/*
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.
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+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; i<MAX_CONTENT+1; i++)
+ {
+ ContentFeatures *f = &g_content_features[i];
+ // Re-initialize
+ f->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; i<MAX_CONTENT+1; i++)
+ {
+ if(i == CONTENT_IGNORE || i == CONTENT_AIR)
+ continue;
+ ContentFeatures *f = &g_content_features[i];
+ f->setAllTextures("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());
+}
+
+
--- /dev/null
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+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 <string>
+#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<std::string, bool> 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
+
#include "materials.h"
#include "mapnode.h"
+#include "mapnode_contentfeatures.h"
// NOTE: DEPRECATED
#include <ITextSceneNode.h>
#endif
#include "settings.h"
+#include "mapnode_contentfeatures.h"
Player::Player():
touching_ground(false),
#include "log.h"
#include "script.h"
#include "scriptapi.h"
+#include "mapnode_contentfeatures.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
#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.
// Initialize stuff
- init_mapnode();
+ // Initialize content feature table
+ init_contentfeatures();
+ // Initialize mapnode content without textures (with g_texturesource=NULL)
+ content_mapnode_init();
+
init_mineral();
/*
#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