Move ContentFeatures to mapnode_contentfeatures.{h,cpp} and clean stuff

This commit is contained in:
Perttu Ahola 2011-11-13 10:57:55 +02:00
parent f8c9b70379
commit 64996422c0
24 changed files with 697 additions and 617 deletions

@ -94,6 +94,7 @@ configure_file(
)
set(common_SRCS
mapnode_contentfeatures.cpp
luaentity_common.cpp
scriptapi.cpp
script.cpp

@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#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),

@ -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<f32> &box_0,

@ -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.

@ -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."<<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");

@ -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);

@ -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<<")"

@ -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

@ -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);

@ -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()
{

@ -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

@ -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<v3s16, MapBlock*> & 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);

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h"
#include "light.h"
#include <sstream>
#include "mapnode_contentfeatures.h"
/*
MapBlock

@ -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)
{

@ -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
{

@ -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 <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.
@ -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.

@ -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<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:
@ -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.

@ -0,0 +1,145 @@
/*
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());
}

@ -0,0 +1,338 @@
/*
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

@ -1,5 +1,6 @@
#include "materials.h"
#include "mapnode.h"
#include "mapnode_contentfeatures.h"
// NOTE: DEPRECATED

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <ITextSceneNode.h>
#endif
#include "settings.h"
#include "mapnode_contentfeatures.h"
Player::Player():
touching_ground(false),

@ -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<<")"

@ -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();
/*

@ -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