diff --git a/data/coalstone.png b/data/coalstone.png
deleted file mode 100644
index 0c62a192f..000000000
Binary files a/data/coalstone.png and /dev/null differ
diff --git a/data/grass.png b/data/grass.png
index 91cc0c0fc..88336c013 100644
Binary files a/data/grass.png and b/data/grass.png differ
diff --git a/data/lump_of_coal.png b/data/lump_of_coal.png
new file mode 100644
index 000000000..bad901efa
Binary files /dev/null and b/data/lump_of_coal.png differ
diff --git a/data/lump_of_iron.png b/data/lump_of_iron.png
new file mode 100644
index 000000000..edb931018
Binary files /dev/null and b/data/lump_of_iron.png differ
diff --git a/data/mineral_coal.png b/data/mineral_coal.png
new file mode 100644
index 000000000..58a4d2b79
Binary files /dev/null and b/data/mineral_coal.png differ
diff --git a/data/mineral_iron.png b/data/mineral_iron.png
new file mode 100644
index 000000000..9698aa006
Binary files /dev/null and b/data/mineral_iron.png differ
diff --git a/data/sand.png b/data/sand.png
new file mode 100644
index 000000000..89149add2
Binary files /dev/null and b/data/sand.png differ
diff --git a/makepackage_binary.sh b/makepackage_binary.sh
index c5248b79b..f00ec608c 100755
--- a/makepackage_binary.sh
+++ b/makepackage_binary.sh
@@ -39,7 +39,6 @@ cp -r data/torch.png $PACKAGEPATH/data/
cp -r data/torch_on_floor.png $PACKAGEPATH/data/
cp -r data/torch_on_ceiling.png $PACKAGEPATH/data/
cp -r data/tree_top.png $PACKAGEPATH/data/
-#cp -r data/mud_with_grass.png $PACKAGEPATH/data/
cp -r data/coalstone.png $PACKAGEPATH/data/
cp -r data/crack.png $PACKAGEPATH/data/
cp -r data/wood.png $PACKAGEPATH/data/
@@ -48,6 +47,11 @@ cp -r data/tool_wpick.png $PACKAGEPATH/data/
cp -r data/tool_stpick.png $PACKAGEPATH/data/
cp -r data/tool_mesepick.png $PACKAGEPATH/data/
cp -r data/grass_side.png $PACKAGEPATH/data/
+cp -r data/lump_of_coal.png $PACKAGEPATH/data/
+cp -r data/lump_of_iron.png $PACKAGEPATH/data/
+cp -r data/mineral_coal.png $PACKAGEPATH/data/
+cp -r data/mineral_iron.png $PACKAGEPATH/data/
+cp -r data/sand.png $PACKAGEPATH/data/
#cp -r data/pauseMenu.gui $PACKAGEPATH/data/
diff --git a/minetest.vcproj b/minetest.vcproj
index 53481add7..71dc5763a 100644
--- a/minetest.vcproj
+++ b/minetest.vcproj
@@ -137,7 +137,7 @@
diff --git a/src/client.cpp b/src/client.cpp
index 36e0f3c7c..915c745b7 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1273,6 +1273,7 @@ void Client::groundAction(u8 action, v3s16 nodepos_undersurface,
0: start digging
1: place block
2: stop digging (all parameters ignored)
+ 3: digging completed
*/
u8 datasize = 2 + 1 + 6 + 6 + 2;
SharedBuffer data(datasize);
diff --git a/src/client.h b/src/client.h
index 9110d33f8..00fd3a5ed 100644
--- a/src/client.h
+++ b/src/client.h
@@ -197,6 +197,40 @@ public:
//void updateSomeExpiredMeshes();
+ void setTempMod(v3s16 p, NodeMod mod)
+ {
+ JMutexAutoLock envlock(m_env_mutex);
+ assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
+
+ core::map affected_blocks;
+ ((ClientMap&)m_env.getMap()).setTempMod(p, mod,
+ &affected_blocks);
+
+ for(core::map::Iterator
+ i = affected_blocks.getIterator();
+ i.atEnd() == false; i++)
+ {
+ i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
+ }
+ }
+ void clearTempMod(v3s16 p)
+ {
+ JMutexAutoLock envlock(m_env_mutex);
+ assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
+
+ core::map affected_blocks;
+ ((ClientMap&)m_env.getMap()).clearTempMod(p,
+ &affected_blocks);
+
+ for(core::map::Iterator
+ i = affected_blocks.getIterator();
+ i.atEnd() == false; i++)
+ {
+ i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
+ }
+ }
+
+#if 0
void setTempMod(v3s16 p, NodeMod mod)
{
JMutexAutoLock envlock(m_env_mutex);
@@ -215,6 +249,7 @@ public:
if(changed)
m_env.getMap().updateMeshes(blockpos, m_env.getDayNightRatio());
}
+#endif
float getAvgRtt()
{
diff --git a/src/inventory.h b/src/inventory.h
index 84ccd5bd6..797a67509 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -122,12 +122,6 @@ public:
#ifndef SERVER
video::ITexture * getImage()
{
- /*if(m_content == CONTENT_TORCH)
- return g_texturecache.get("torch_on_floor");
-
- u16 tile = content_tile(m_content, v3s16(1,0,0));
- return g_tile_contents[tile].getTexture(0);*/
-
if(m_content >= USEFUL_CONTENT_COUNT)
return NULL;
@@ -257,15 +251,18 @@ public:
video::ITexture * getImage()
{
std::string basename;
+
if(m_subname == "Stick")
- basename = porting::getDataPath("stick.png").c_str();
- // Default to cloud texture
+ basename = porting::getDataPath("stick.png");
+ else if(m_subname == "lump_of_coal")
+ basename = porting::getDataPath("lump_of_coal.png");
+ else if(m_subname == "lump_of_iron")
+ basename = porting::getDataPath("lump_of_iron.png");
else
- basename = tile_texture_path_get(TILE_CLOUD);
+ basename = porting::getDataPath("cloud.png[[mod:crack3");
// Get such a texture
return g_irrlicht->getTexture(basename);
- //return g_irrlicht->getTexture(TextureSpec(finalname, basename, mod));
}
#endif
std::string getText()
@@ -340,7 +337,8 @@ public:
basename = porting::getDataPath("tool_mesepick.png").c_str();
// Default to cloud texture
else
- basename = tile_texture_path_get(TILE_CLOUD);
+ basename = porting::getDataPath("cloud.png").c_str();
+ //basename = tile_texture_path_get(TILE_CLOUD);
/*
Calculate some progress value with sane amount of
@@ -350,6 +348,12 @@ public:
u32 toolprogress = (65535-m_wear)/(65535/maxprogress);
// Make texture name for the new texture with a progress bar
+ float value_f = (float)toolprogress / (float)maxprogress;
+ std::ostringstream os;
+ os<getTexture(os.str());
+
+ /*// Make texture name for the new texture with a progress bar
std::ostringstream os;
os<getTexture(TextureSpec(finalname, basename, mod));
+ return g_irrlicht->getTexture(TextureSpec(finalname, basename, mod));*/
}
#endif
std::string getText()
diff --git a/src/irrlichtwrapper.cpp b/src/irrlichtwrapper.cpp
index e26cbfd15..4e1ebdd74 100644
--- a/src/irrlichtwrapper.cpp
+++ b/src/irrlichtwrapper.cpp
@@ -1,5 +1,7 @@
#include "irrlichtwrapper.h"
#include "constants.h"
+#include "string.h"
+#include "strfnd.h"
IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
{
@@ -15,13 +17,13 @@ void IrrlichtWrapper::Run()
*/
if(m_get_texture_queue.size() > 0)
{
- GetRequest
+ GetRequest
request = m_get_texture_queue.pop();
- dstream<<"got texture request with key.name="
- <
+ GetResult
result = result_queue.pop_front(1000);
// Check that at least something worked OK
- assert(result.key.name == spec.name);
+ assert(result.key == spec);
t = result.item;
}
@@ -74,44 +79,63 @@ video::ITexture* IrrlichtWrapper::getTexture(TextureSpec spec)
}
// Add to cache and return
- m_texturecache.set(spec.name, t);
+ m_texturecache.set(spec, t);
return t;
}
-video::ITexture* IrrlichtWrapper::getTexture(const std::string &path)
-{
- return getTexture(TextureSpec(path, path, NULL));
-}
-
/*
Non-thread-safe functions
*/
-video::ITexture* IrrlichtWrapper::getTextureDirect(TextureSpec spec)
-{
- video::IVideoDriver* driver = m_device->getVideoDriver();
-
- if(spec.mod == NULL)
- {
- dstream<<"IrrlichtWrapper::getTextureDirect: Loading texture "
- <getTexture(spec.path.c_str());
- }
+/*
+ Texture modifier functions
+*/
- dstream<<"IrrlichtWrapper::getTextureDirect: Loading and modifying "
- "texture "<getTexture(spec.path.c_str());
- video::ITexture *result = spec.mod->make(base, spec.name.c_str(), driver);
-
- delete spec.mod;
-
- return result;
-}
-
-video::ITexture * CrackTextureMod::make(video::ITexture *original,
+// blitted_name = eg. "mineral_coal.png"
+video::ITexture * make_blitname(const std::string &blitted_name,
+ video::ITexture *original,
const char *newname, video::IVideoDriver* driver)
{
+ if(original == NULL)
+ return NULL;
+
+ // Size of the base image
+ core::dimension2d dim(16, 16);
+ // Position to copy the blitted to in the base image
+ core::position2d pos_base(0, 0);
+ // Position to copy the blitted from in the blitted image
+ core::position2d pos_other(0, 0);
+
+ video::IImage *baseimage = driver->createImage(original, pos_base, dim);
+ assert(baseimage);
+
+ video::IImage *blittedimage = driver->createImageFromFile(porting::getDataPath(blitted_name.c_str()).c_str());
+ assert(blittedimage);
+
+ // Then copy the right part of blittedimage to baseimage
+
+ blittedimage->copyToWithAlpha(baseimage, v2s32(0,0),
+ core::rect(pos_other, dim),
+ video::SColor(255,255,255,255),
+ NULL);
+
+ blittedimage->drop();
+
+ // Create texture from resulting image
+
+ video::ITexture *newtexture = driver->addTexture(newname, baseimage);
+
+ baseimage->drop();
+
+ return newtexture;
+}
+
+video::ITexture * make_crack(u16 progression, video::ITexture *original,
+ const char *newname, video::IVideoDriver* driver)
+{
+ if(original == NULL)
+ return NULL;
+
// Size of the base image
core::dimension2d dim(16, 16);
// Size of the crack image
@@ -127,36 +151,6 @@ video::ITexture * CrackTextureMod::make(video::ITexture *original,
video::IImage *crackimage = driver->createImageFromFile(porting::getDataPath("crack.png").c_str());
assert(crackimage);
-#if 0
- video::ITexture *other = driver->getTexture(porting::getDataPath("crack.png").c_str());
-
- dstream<<__FUNCTION_NAME<<": crack texture size is "
- <getSize().Width<<"x"
- <getSize().Height<createImage(
- other, core::position2d(0,0), other->getSize());
-
- assert(otherimage);
-
- // Now, the image might be 80 or 128 high depending on the computer
- // Let's make an image of the right size and copy the possibly
- // wrong sized one with scaling
- // NOTE: This is an ugly hack.
-
- video::IImage *crackimage = driver->createImage(
- baseimage->getColorFormat(), dim_crack);
-
- assert(crackimage);
-
- otherimage->copyToScaling(crackimage);
- otherimage->drop();
-#endif
-
// Then copy the right part of crackimage to baseimage
crackimage->copyToWithAlpha(baseimage, v2s32(0,0),
@@ -175,9 +169,13 @@ video::ITexture * CrackTextureMod::make(video::ITexture *original,
return newtexture;
}
-video::ITexture * SideGrassTextureMod::make(video::ITexture *original,
+#if 0
+video::ITexture * make_sidegrass(video::ITexture *original,
const char *newname, video::IVideoDriver* driver)
{
+ if(original == NULL)
+ return NULL;
+
// Size of the base image
core::dimension2d dim(16, 16);
// Position to copy the grass to in the base image
@@ -208,10 +206,14 @@ video::ITexture * SideGrassTextureMod::make(video::ITexture *original,
return newtexture;
}
+#endif
-video::ITexture * ProgressBarTextureMod::make(video::ITexture *original,
+video::ITexture * make_progressbar(float value, video::ITexture *original,
const char *newname, video::IVideoDriver* driver)
{
+ if(original == NULL)
+ return NULL;
+
core::position2d pos_base(0, 0);
core::dimension2d dim = original->getOriginalSize();
@@ -251,3 +253,166 @@ video::ITexture * ProgressBarTextureMod::make(video::ITexture *original,
return newtexture;
}
+/*
+ Texture fetcher/maker function, called always from the main thread
+*/
+
+video::ITexture* IrrlichtWrapper::getTextureDirect(const std::string &spec)
+{
+ if(spec == "")
+ return NULL;
+
+ video::IVideoDriver* driver = m_device->getVideoDriver();
+
+ /*
+ Input (spec) is something like this:
+ "/usr/share/minetest/stone.png[[mod:mineral0[[mod:crack3"
+ */
+
+ video::ITexture* t = NULL;
+ std::string modmagic = "[[mod:";
+ Strfnd f(spec);
+ std::string path = f.next(modmagic);
+ t = driver->getTexture(path.c_str());
+ std::string texture_name = path;
+ while(f.atend() == false)
+ {
+ std::string mod = f.next(modmagic);
+ texture_name += modmagic + mod;
+ dstream<<"Making texture \""<= spec.size())
+ {
+ strcache[length] = '\0';
+ // Now our string is in strcache, ending in \0
+
+ if(readmode == READMODE_PATH)
+ {
+ // Get initial texture (strcache is path)
+ assert(t == NULL);
+ t = driver->getTexture(strcache);
+ readmode = READMODE_MOD;
+ path = strcache;
+ strcache = (char*)malloc(specsize);
+ assert(strcache);
+ }
+ else
+ {
+ dstream<<"Parsing mod \""<= spec.size())
+ break;
+ }
+
+ /*if(spec.mod == NULL)
+ {
+ dstream<<"IrrlichtWrapper::getTextureDirect: Loading texture "
+ <getTexture(spec.path.c_str());
+ }
+
+ dstream<<"IrrlichtWrapper::getTextureDirect: Loading and modifying "
+ "texture "<getTexture(spec.path.c_str());
+ video::ITexture *result = spec.mod->make(base, spec.name.c_str(), driver);
+
+ delete spec.mod;*/
+
+ if(strcache)
+ free(strcache);
+ if(path)
+ free(path);
+
+ return t;
+#endif
+}
+
+
diff --git a/src/irrlichtwrapper.h b/src/irrlichtwrapper.h
index 97607e579..2506af012 100644
--- a/src/irrlichtwrapper.h
+++ b/src/irrlichtwrapper.h
@@ -56,7 +56,7 @@ public:
m_textures[name] = texture;
}
- video::ITexture* get(std::string name)
+ video::ITexture* get(const std::string &name)
{
JMutexAutoLock lock(m_mutex);
@@ -74,86 +74,6 @@ private:
JMutex m_mutex;
};
-struct TextureMod
-{
- /*
- Returns a new texture which can be based on the original.
- Shall not modify or delete the original texture.
- */
- virtual video::ITexture * make(video::ITexture *original,
- const char *newname, video::IVideoDriver* driver) = 0;
-};
-
-struct CrackTextureMod: public TextureMod
-{
- CrackTextureMod(u16 a_progression)
- {
- progression = a_progression;
- }
-
- virtual video::ITexture * make(video::ITexture *original,
- const char *newname, video::IVideoDriver* driver);
-
- u16 progression;
-};
-
-struct SideGrassTextureMod: public TextureMod
-{
- SideGrassTextureMod()
- {
- }
-
- virtual video::ITexture * make(video::ITexture *original,
- const char *newname, video::IVideoDriver* driver);
-};
-
-struct ProgressBarTextureMod: public TextureMod
-{
- // value is from 0.0 to 1.0
- ProgressBarTextureMod(float a_value)
- {
- value = a_value;
- }
-
- virtual video::ITexture * make(video::ITexture *original,
- const char *newname, video::IVideoDriver* driver);
-
- float value;
-};
-
-/*
- A class for specifying a requested texture
-*/
-struct TextureSpec
-{
- TextureSpec()
- {
- mod = NULL;
- }
- TextureSpec(const std::string &a_name, const std::string &a_path,
- TextureMod *a_mod)
- {
- name = a_name;
- path = a_path;
- mod = a_mod;;
- }
- ~TextureSpec()
- {
- }
- bool operator==(const TextureSpec &other)
- {
- return name == other.name;
- }
- // An unique name for the texture. Usually the same as the path.
- // Note that names and paths reside the same namespace.
- std::string name;
- // This is the path of the base texture
- std::string path;
- // Modification to do to the base texture
- // NOTE: This is deleted by the one who processes the request
- TextureMod *mod;
-};
-
/*
A thread-safe wrapper for irrlicht, to be accessed from
background worker threads.
@@ -183,14 +103,17 @@ public:
return m_device->getTimer()->getRealTime();
}
- video::ITexture* getTexture(TextureSpec spec);
- video::ITexture* getTexture(const std::string &path);
-
+ /*
+ Path can contain stuff like
+ "/usr/share/minetest/stone.png[[mod:mineral0[[mod:crack3"
+ */
+ video::ITexture* getTexture(const std::string &spec);
+
private:
/*
Non-thread-safe variants of stuff, for internal use
*/
- video::ITexture* getTextureDirect(TextureSpec spec);
+ video::ITexture* getTextureDirect(const std::string &spec);
/*
Members
@@ -203,7 +126,7 @@ private:
TextureCache m_texturecache;
- RequestQueue m_get_texture_queue;
+ RequestQueue m_get_texture_queue;
};
#endif
diff --git a/src/map.cpp b/src/map.cpp
index 0b5872e05..2782cef03 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h"
#include "voxel.h"
#include "porting.h"
+#include "mineral.h"
/*
Map
@@ -627,9 +628,8 @@ void Map::updateLighting(enum LightBank bank,
//TimeTaker timer("updateLighting");
// For debugging
- bool debug=true;
-
- u32 count_was = modified_blocks.size();
+ //bool debug=true;
+ //u32 count_was = modified_blocks.size();
core::map light_sources;
@@ -1835,9 +1835,18 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
randfactor = 0.5;
}*/
- baseheight = 0;
- randmax = 15;
- randfactor = 0.63;
+ if(myrand()%3 < 2)
+ {
+ baseheight = 10;
+ randmax = 30;
+ randfactor = 0.7;
+ }
+ else
+ {
+ baseheight = 0;
+ randmax = 15;
+ randfactor = 0.63;
+ }
list_baseheight->addPoint(p, Attribute(baseheight));
list_randmax->addPoint(p, Attribute(randmax));
@@ -2699,7 +2708,7 @@ continue_generating:
+ued*(y0*ued/MAP_BLOCKSIZE)
+(x0*ued/MAP_BLOCKSIZE)])
{
- if(is_ground_content(n.d))
+ if(content_features(n.d).walkable/*is_ground_content(n.d)*/)
{
// Has now caves
has_dungeons = true;
@@ -2755,17 +2764,11 @@ continue_generating:
MapNode n;
n.d = CONTENT_MESE;
- //if(is_ground_content(block->getNode(cp).d))
- if(block->getNode(cp).d == CONTENT_STONE)
- if(myrand()%8 == 0)
- block->setNode(cp, n);
-
- for(u16 i=0; i<26; i++)
+ for(u16 i=0; i<27; i++)
{
- //if(is_ground_content(block->getNode(cp+g_26dirs[i]).d))
- if(block->getNode(cp+g_26dirs[i]).d == CONTENT_STONE)
+ if(block->getNode(cp+g_27dirs[i]).d == CONTENT_STONE)
if(myrand()%8 == 0)
- block->setNode(cp+g_26dirs[i], n);
+ block->setNode(cp+g_27dirs[i], n);
}
}
}
@@ -2790,21 +2793,47 @@ continue_generating:
);
MapNode n;
- n.d = CONTENT_COALSTONE;
+ n.d = CONTENT_STONE;
+ n.param = MINERAL_COAL;
- //dstream<<"Adding coalstone"<getNode(cp).d))
- if(block->getNode(cp).d == CONTENT_STONE)
- if(myrand()%8 == 0)
- block->setNode(cp, n);
-
- for(u16 i=0; i<26; i++)
+ for(u16 i=0; i<27; i++)
{
- //if(is_ground_content(block->getNode(cp+g_26dirs[i]).d))
- if(block->getNode(cp+g_26dirs[i]).d == CONTENT_STONE)
+ if(block->getNode(cp+g_27dirs[i]).d == CONTENT_STONE)
if(myrand()%8 == 0)
- block->setNode(cp+g_26dirs[i], n);
+ block->setNode(cp+g_27dirs[i], n);
+ }
+ }
+ }
+
+ /*
+ Add iron
+ */
+ //TODO: change to iron_amount or whatever
+ u16 iron_amount = 30.0 * g_settings.getFloat("coal_amount");
+ u16 iron_rareness = 60 / iron_amount;
+ if(iron_rareness == 0)
+ iron_rareness = 1;
+ if(myrand()%iron_rareness == 0)
+ {
+ u16 a = myrand() % 16;
+ u16 amount = iron_amount * a*a*a / 1000;
+ for(s16 i=0; igetNode(cp+g_27dirs[i]).d == CONTENT_STONE)
+ if(myrand()%8 == 0)
+ block->setNode(cp+g_27dirs[i], n);
}
}
}
@@ -3012,26 +3041,23 @@ continue_generating:
<getNode(p2).d)
- && !is_mineral(sector->getNode(p2).d))
+ //if(is_ground_content(sector->getNode(p2).d))
+ if(content_features(sector->getNode(p2).d).walkable)
sector->setNode(p2, n);
}
{
v3s16 p2 = p + v3s16(x,y,z-1);
- if(is_ground_content(sector->getNode(p2).d)
- && !is_mineral(sector->getNode(p2).d))
+ if(content_features(sector->getNode(p2).d).walkable)
sector->setNode(p2, n2);
}
{
v3s16 p2 = p + v3s16(x,y,z+0);
- if(is_ground_content(sector->getNode(p2).d)
- && !is_mineral(sector->getNode(p2).d))
+ if(content_features(sector->getNode(p2).d).walkable)
sector->setNode(p2, n2);
}
{
v3s16 p2 = p + v3s16(x,y,z+1);
- if(is_ground_content(sector->getNode(p2).d)
- && !is_mineral(sector->getNode(p2).d))
+ if(content_features(sector->getNode(p2).d).walkable)
sector->setNode(p2, n);
}
@@ -4027,8 +4053,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
<<", rendered "< *affected_blocks)
{
+ bool changed = false;
/*
Add it to all blocks touching it
*/
@@ -4053,14 +4081,29 @@ v3s16 ClientMap::setTempMod(v3s16 p, NodeMod mod, bool *changed)
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
if(blockref->setTempMod(relpos, mod))
{
- if(changed != NULL)
- *changed = true;
+ changed = true;
}
}
- return getNodeBlockPos(p);
+ if(changed && affected_blocks!=NULL)
+ {
+ for(u16 i=0; i<7; i++)
+ {
+ v3s16 p2 = p + dirs[i];
+ // Block position of neighbor (or requested) node
+ v3s16 blockpos = getNodeBlockPos(p2);
+ MapBlock * blockref = getBlockNoCreateNoEx(blockpos);
+ if(blockref == NULL)
+ continue;
+ affected_blocks->insert(blockpos, blockref);
+ }
+ }
+ return changed;
}
-v3s16 ClientMap::clearTempMod(v3s16 p, bool *changed)
+
+bool ClientMap::clearTempMod(v3s16 p,
+ core::map *affected_blocks)
{
+ bool changed = false;
v3s16 dirs[7] = {
v3s16(0,0,0), // this
v3s16(0,0,1), // back
@@ -4082,11 +4125,23 @@ v3s16 ClientMap::clearTempMod(v3s16 p, bool *changed)
v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
if(blockref->clearTempMod(relpos))
{
- if(changed != NULL)
- *changed = true;
+ changed = true;
}
}
- return getNodeBlockPos(p);
+ if(changed && affected_blocks!=NULL)
+ {
+ for(u16 i=0; i<7; i++)
+ {
+ v3s16 p2 = p + dirs[i];
+ // Block position of neighbor (or requested) node
+ v3s16 blockpos = getNodeBlockPos(p2);
+ MapBlock * blockref = getBlockNoCreateNoEx(blockpos);
+ if(blockref == NULL)
+ continue;
+ affected_blocks->insert(blockpos, blockref);
+ }
+ }
+ return changed;
}
void ClientMap::PrintInfo(std::ostream &out)
@@ -4216,7 +4271,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
/*
- TODO: Add an option to only update eg. water and air nodes.
+ SUGG: Add an option to only update eg. water and air nodes.
This will make it interfere less with important stuff if
run on background.
*/
diff --git a/src/map.h b/src/map.h
index 787e1240f..9140d4bf2 100644
--- a/src/map.h
+++ b/src/map.h
@@ -204,10 +204,13 @@ public:
void expireMeshes(bool only_daynight_diffed);
/*
- Updates the faces of the given block and blocks on the
+ Update the faces of the given block and blocks on the
leading edge.
*/
void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
+
+ // Update meshes that touch the node
+ //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
#endif
/*
@@ -483,10 +486,16 @@ public:
/*
Methods for setting temporary modifications to nodes for
drawing.
- Return value is position of changed block.
+
+ Returns true if something changed.
+
+ All blocks whose mesh could have been changed are inserted
+ to affected_blocks.
*/
- v3s16 setTempMod(v3s16 p, NodeMod mod, bool *changed=NULL);
- v3s16 clearTempMod(v3s16 p, bool *changed=NULL);
+ bool setTempMod(v3s16 p, NodeMod mod,
+ core::map *affected_blocks=NULL);
+ bool clearTempMod(v3s16 p,
+ core::map *affected_blocks=NULL);
// Efficient implementation needs a cache of TempMods
//void clearTempMods();
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 3eb65b4da..484821d50 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -264,12 +264,10 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
//u8 li = decode_light(light);
u8 li = light;
- u8 alpha = 255;
-
+ u8 alpha = tile.alpha;
+ /*u8 alpha = 255;
if(tile.id == TILE_WATER)
- {
- alpha = WATER_ALPHA;
- }
+ alpha = WATER_ALPHA;*/
video::SColor c = video::SColor(alpha,li,li,li);
@@ -297,17 +295,8 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
{
TileSpec spec;
-
- /*//DEBUG
- {
- spec.id = TILE_STONE;
- return spec;
- }*/
-
- spec.feature = TILEFEAT_NONE;
- //spec.id = TILE_STONE;
- spec.id = mn.getTile(face_dir);
-
+ spec = mn.getTile(face_dir);
+
/*
Check temporary modifications on this node
*/
@@ -320,12 +309,15 @@ TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
struct NodeMod mod = n->getValue();
if(mod.type == NODEMOD_CHANGECONTENT)
{
- spec.id = content_tile(mod.param, face_dir);
+ //spec = content_tile(mod.param, face_dir);
+ MapNode mn2(mod.param);
+ spec = mn2.getTile(face_dir);
}
if(mod.type == NODEMOD_CRACK)
{
- spec.feature = TILEFEAT_CRACK;
- spec.param.crack.progression = mod.param;
+ std::ostringstream os;
+ os<<"[[mod:crack"<getTexture(f.tile.name);
+ video::SMaterial material;
+ material.Lighting = false;
+ material.BackfaceCulling = false;
+ material.setFlag(video::EMF_BILINEAR_FILTER, false);
+ material.setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
+ material.setFlag(video::EMF_FOG_ENABLE, true);
+ material.setTexture(0, texture);
+ if(f.tile.alpha != 255)
+ material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
- if(f.tile.feature == TILEFEAT_NONE)
- {
- collector.append(tile_material_get(f.tile.id), f.vertices, 4,
- indices, 6);
- }
- else if(f.tile.feature == TILEFEAT_CRACK)
- {
- const char *path = tile_texture_path_get(f.tile.id);
-
- u16 progression = f.tile.param.crack.progression;
-
- std::string name = (std::string)path + "_cracked_"
- + (char)('0' + progression);
-
- TextureMod *mod = new CrackTextureMod(progression);
-
- video::ITexture *texture = g_irrlicht->getTexture(
- TextureSpec(name, path, mod));
-
- video::SMaterial material = tile_material_get(f.tile.id);
- material.setTexture(0, texture);
-
- collector.append(material, f.vertices, 4, indices, 6);
- }
- else
- {
- // No such feature
- assert(0);
- }
+ collector.append(material, f.vertices, 4, indices, 6);
}
}
@@ -1427,7 +1402,8 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
s16 y = MAP_BLOCKSIZE-1;
for(; y>=0; y--)
{
- if(is_ground_content(getNodeRef(p2d.X, y, p2d.Y).d))
+ //if(is_ground_content(getNodeRef(p2d.X, y, p2d.Y).d))
+ if(content_features(getNodeRef(p2d.X, y, p2d.Y).d).walkable)
{
if(y == MAP_BLOCKSIZE-1)
return -2;
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 59e40935c..ebae055db 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -21,61 +21,197 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tile.h"
#include "porting.h"
#include
+#include "mineral.h"
-/*
- Face directions:
- 0: up
- 1: down
- 2: right
- 3: left
- 4: back
- 5: front
-*/
-u16 g_content_tiles[USEFUL_CONTENT_COUNT][6] =
+ContentFeatures::~ContentFeatures()
{
- {TILE_STONE,TILE_STONE,TILE_STONE,TILE_STONE,TILE_STONE,TILE_STONE},
- {TILE_GRASS,TILE_MUD,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS},
- //{TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER},
- {TILE_NONE,TILE_NONE,TILE_NONE,TILE_NONE,TILE_NONE,TILE_NONE},
- {TILE_NONE,TILE_NONE,TILE_NONE,TILE_NONE,TILE_NONE,TILE_NONE},
- {TILE_TREE_TOP,TILE_TREE_TOP,TILE_TREE,TILE_TREE,TILE_TREE,TILE_TREE},
- {TILE_LEAVES,TILE_LEAVES,TILE_LEAVES,TILE_LEAVES,TILE_LEAVES,TILE_LEAVES},
- {TILE_GRASS_FOOTSTEPS,TILE_MUD,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS,TILE_MUD_WITH_GRASS},
- {TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE},
- {TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD},
- {TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER}, // ocean
- {TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD},
- {TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE},
- {TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD,TILE_WOOD},
-};
+ if(translate_to)
+ delete translate_to;
+}
-std::string g_content_inventory_texture_strings[USEFUL_CONTENT_COUNT];
-// Pointers to c_str()s of the above
+struct ContentFeatures g_content_features[256];
+
+void init_mapnode()
+{
+ u8 i;
+ ContentFeatures *f = NULL;
+
+ i = CONTENT_STONE;
+ f = &g_content_features[i];
+ f->setAllTextures("stone.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_GRASS;
+ f = &g_content_features[i];
+ //f->setAllTextures("mud.png[[mod:sidegrass");
+ f->setAllTextures("mud.png[[mod:blitname:grass_side.png");
+ f->setTexture(0, "grass.png");
+ f->setTexture(1, "mud.png");
+ f->setInventoryImage("grass.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_GRASS_FOOTSTEPS;
+ f = &g_content_features[i];
+ //f->setAllTextures("mud.png[[mod:sidegrass");
+ f->setAllTextures("mud.png[[mod:blitname:grass_side.png");
+ f->setTexture(0, "grass_footsteps.png");
+ f->setTexture(1, "mud.png");
+ f->setInventoryImage("grass_footsteps.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_MUD;
+ f = &g_content_features[i];
+ f->setAllTextures("mud.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_SAND;
+ f = &g_content_features[i];
+ f->setAllTextures("mud.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_TREE;
+ f = &g_content_features[i];
+ f->setAllTextures("tree.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_LEAVES;
+ f = &g_content_features[i];
+ f->setAllTextures("leaves.png");
+ f->param_type = CPT_MINERAL;
+ f->is_ground_content = true;
+
+ i = CONTENT_COALSTONE;
+ f = &g_content_features[i];
+ f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL);
+ /*f->setAllTextures("coalstone.png");
+ f->is_ground_content = true;*/
+
+ i = CONTENT_WOOD;
+ f = &g_content_features[i];
+ f->setAllTextures("wood.png");
+ f->is_ground_content = true;
+
+ i = CONTENT_MESE;
+ f = &g_content_features[i];
+ f->setAllTextures("mese.png");
+ f->is_ground_content = true;
+
+ i = CONTENT_CLOUD;
+ f = &g_content_features[i];
+ f->setAllTextures("cloud.png");
+ f->is_ground_content = true;
+
+ i = CONTENT_AIR;
+ f = &g_content_features[i];
+ f->param_type = CPT_LIGHT;
+ f->light_propagates = true;
+ f->sunlight_propagates = true;
+ f->solidness = 0;
+ f->walkable = false;
+ f->pointable = false;
+ f->diggable = false;
+ f->buildable_to = true;
+
+ i = CONTENT_WATER;
+ f = &g_content_features[i];
+ f->setInventoryImage("water.png");
+ f->param_type = CPT_LIGHT;
+ f->light_propagates = true;
+ f->solidness = 0; // Drawn separately, makes no faces
+ f->walkable = false;
+ f->pointable = false;
+ f->diggable = false;
+ f->buildable_to = true;
+ f->liquid_type = LIQUID_FLOWING;
+
+ i = CONTENT_WATERSOURCE;
+ f = &g_content_features[i];
+ f->setTexture(0, "water.png", WATER_ALPHA);
+ f->setInventoryImage("water.png");
+ f->param_type = CPT_LIGHT;
+ f->light_propagates = true;
+ f->solidness = 1;
+ f->walkable = false;
+ f->pointable = false;
+ f->diggable = false;
+ f->buildable_to = true;
+ f->liquid_type = LIQUID_SOURCE;
+
+ i = CONTENT_TORCH;
+ f = &g_content_features[i];
+ f->setInventoryImage("torch_on_floor.png");
+ f->param_type = CPT_LIGHT;
+ f->light_propagates = true;
+ f->solidness = 0; // drawn separately, makes no faces
+ f->walkable = false;
+ f->wall_mounted = true;
+
+}
+
+TileSpec MapNode::getTile(v3s16 dir)
+{
+ TileSpec spec;
+
+ s32 dir_i = -1;
+
+ if(dir == v3s16(0,1,0))
+ dir_i = 0;
+ else if(dir == v3s16(0,-1,0))
+ dir_i = 1;
+ else if(dir == v3s16(1,0,0))
+ dir_i = 2;
+ else if(dir == v3s16(-1,0,0))
+ dir_i = 3;
+ else if(dir == v3s16(0,0,1))
+ dir_i = 4;
+ else if(dir == v3s16(0,0,-1))
+ dir_i = 5;
+
+ if(dir_i == -1)
+ // Non-directional
+ spec = content_features(d).tiles[0];
+ else
+ spec = content_features(d).tiles[dir_i];
+
+ if(content_features(d).param_type == CPT_MINERAL)
+ {
+ u8 mineral = param & 0x1f;
+ const char *ts = mineral_block_texture(mineral);
+ if(ts[0] != 0)
+ {
+ spec.name += "[[mod:blitname:";
+ spec.name += ts;
+ }
+ }
+
+ return spec;
+}
+
+u8 MapNode::getMineral()
+{
+ if(content_features(d).param_type == CPT_MINERAL)
+ {
+ return param & 0x1f;
+ }
+
+ return MINERAL_NONE;
+}
+
+// Pointers to c_str()s g_content_features[i].inventory_image_path
const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0};
-const char * g_content_inventory_texture_paths_base[USEFUL_CONTENT_COUNT] =
-{
- "stone.png",
- "grass.png",
- "water.png",
- "torch_on_floor.png",
- "tree_top.png",
- "leaves.png",
- "grass_footsteps.png",
- "mese.png",
- "mud.png",
- "water.png", //ocean
- "cloud.png",
- "coalstone.png",
- "wood.png",
-};
-
void init_content_inventory_texture_paths()
{
for(u16 i=0; i CONTENT_WATER
@@ -146,57 +276,35 @@ inline u8 make_liquid_flowing(u8 m)
}
// Pointable contents can be pointed to in the map
+// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_pointable(u8 m)
{
- return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
+ return g_content_features[m].pointable;
+ //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
}
+// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_diggable(u8 m)
{
- return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
+ return g_content_features[m].diggable;
+ //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE);
}
+// NOTE: Don't use, use "content_features(m).whatever" instead
inline bool content_buildable_to(u8 m)
{
- return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
+ return g_content_features[m].buildable_to;
+ //return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE);
}
/*
Returns true for contents that form the base ground that
follows the main heightmap
*/
-inline bool is_ground_content(u8 m)
+/*inline bool is_ground_content(u8 m)
{
- return (
- m != CONTENT_IGNORE
- && m != CONTENT_AIR
- && m != CONTENT_WATER
- && m != CONTENT_TORCH
- && m != CONTENT_TREE
- && m != CONTENT_LEAVES
- && m != CONTENT_WATERSOURCE
- && m != CONTENT_CLOUD
- );
-}
-
-inline bool is_mineral(u8 c)
-{
- return(c == CONTENT_MESE
- || c == CONTENT_COALSTONE);
-}
-
-inline bool liquid_replaces_content(u8 c)
-{
- return (c == CONTENT_AIR || c == CONTENT_TORCH);
-}
-
-/*
- When placing a node, drection info is added to it if this is true
-*/
-inline bool content_directional(u8 c)
-{
- return (c == CONTENT_TORCH);
-}
+ return g_content_features[m].is_ground_content;
+}*/
/*
Nodes make a face if contents differ and solidness differs.
@@ -275,87 +383,15 @@ inline v3s16 unpackDir(u8 b)
return d;
}
-inline u16 content_tile(u8 c, v3s16 dir)
-{
- if(c == CONTENT_IGNORE || c == CONTENT_AIR
- || c >= USEFUL_CONTENT_COUNT)
- return TILE_NONE;
-
- s32 dir_i = -1;
-
- if(dir == v3s16(0,1,0))
- dir_i = 0;
- else if(dir == v3s16(0,-1,0))
- dir_i = 1;
- else if(dir == v3s16(1,0,0))
- dir_i = 2;
- else if(dir == v3s16(-1,0,0))
- dir_i = 3;
- else if(dir == v3s16(0,0,1))
- dir_i = 4;
- else if(dir == v3s16(0,0,-1))
- dir_i = 5;
-
- /*if(dir_i == -1)
- return TILE_NONE;*/
- assert(dir_i != -1);
-
- return g_content_tiles[c][dir_i];
-}
-
enum LightBank
{
LIGHTBANK_DAY,
LIGHTBANK_NIGHT
};
-#if 0
-#define DIR_PX 1 //X+
-#define DIR_NX 2 //X-
-#define DIR_PZ 4 //Z+
-#define DIR_NZ 8 //Z-
-#define DIR_PY 16 //Y+
-#define DIR_NY 32 //Y-
-
-inline void decode_dirs(u8 b, core::list &dirs)
-{
- if(b & DIR_PX)
- dirs.push_back(v3s16(1,0,0));
- if(b & DIR_NX)
- dirs.push_back(v3s16(-1,0,0));
- if(b & DIR_PZ)
- dirs.push_back(v3s16(0,0,1));
- if(b & DIR_NZ)
- dirs.push_back(v3s16(0,0,-1));
- if(b & DIR_PY)
- dirs.push_back(v3s16(0,1,0));
- if(b & DIR_NY)
- dirs.push_back(v3s16(0,-1,0));
-}
-
-inline u8 encode_dirs(core::list &dirs)
-{
- u8 b = 0;
- for(core::list::Iterator
- i = dirs.begin();
- i != dirs.end(); i++)
- {
- if(*i == v3s16(1,0,0))
- b += DIR_PX;
- else if(*i == v3s16(-1,0,0))
- b += DIR_NX;
- else if(*i == v3s16(0,0,1))
- b += DIR_PZ;
- else if(*i == v3s16(0,0,-1))
- b += DIR_NZ;
- else if(*i == v3s16(0,1,0))
- b += DIR_PY;
- else if(*i == v3s16(0,-1,0))
- b += DIR_NY;
- }
- return b;
-}
-#endif
+/*
+ This is the stuff what the whole world consists of.
+*/
struct MapNode
{
@@ -511,11 +547,11 @@ struct MapNode
else
assert(0);
}
+
+ // In mapnode.cpp
+ TileSpec getTile(v3s16 dir);
- u16 getTile(v3s16 dir)
- {
- return content_tile(d, dir);
- }
+ u8 getMineral();
/*
These serialization functions are used when informing client
@@ -584,6 +620,15 @@ struct MapNode
param = source[1];
param2 = source[2];
}
+
+ // Translate deprecated stuff
+ MapNode *translate_to = g_content_features[d].translate_to;
+ if(translate_to)
+ {
+ dstream<<"MapNode: WARNING: Translating "<d<
+
+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 MINERAL_HEADER
+#define MINERAL_HEADER
+
+#include "inventory.h"
+
+/*
+ Minerals
+
+ Value is stored in the lowest 5 bits of a MapNode's CPT_MINERAL
+ type param.
+*/
+
+#define MINERAL_NONE 0
+#define MINERAL_COAL 1
+#define MINERAL_IRON 2
+
+inline const char * mineral_block_texture(u8 mineral)
+{
+ switch(mineral)
+ {
+ case MINERAL_COAL:
+ return "mineral_coal.png";
+ case MINERAL_IRON:
+ return "mineral_iron.png";
+ default:
+ return "";
+ }
+}
+
+inline CraftItem * getDiggedMineralItem(u8 mineral)
+{
+ if(mineral == MINERAL_COAL)
+ return new CraftItem("lump_of_coal", 1);
+ else if(mineral == MINERAL_IRON)
+ return new CraftItem("lump_of_iron", 1);
+
+ return NULL;
+}
+
+#endif
+
diff --git a/src/server.cpp b/src/server.cpp
index 505e9730f..541582b65 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "constants.h"
#include "voxel.h"
#include "materials.h"
+#include "mineral.h"
#define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
@@ -1951,11 +1952,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
core::map modified_blocks;
u8 material;
+ u8 mineral = MINERAL_NONE;
try
{
+ MapNode n = m_env.getMap().getNode(p_under);
// Get material at position
- material = m_env.getMap().getNode(p_under).d;
+ material = n.d;
// If it's not diggable, do nothing
if(content_diggable(material) == false)
{
@@ -1963,6 +1966,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<inventory.addItem("main", item);
/*
@@ -2134,7 +2145,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
MaterialItem *mitem = (MaterialItem*)item;
MapNode n;
n.d = mitem->getMaterial();
- if(content_directional(n.d))
+ if(content_features(n.d).wall_mounted)
n.dir = packDir(p_under - p_over);
#if 1
@@ -2939,7 +2950,7 @@ void Server::SendInventory(u16 peer_id)
if(!found)
{
ItemSpec specs[9];
- specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COALSTONE);
+ specs[0] = ItemSpec(ITEM_CRAFT, "Coal");
specs[3] = ItemSpec(ITEM_CRAFT, "Stick");
if(checkItemCombination(items, specs))
{
@@ -3300,6 +3311,11 @@ Player *Server::emergePlayer(const char *name, const char *password,
}
else
{
+ {
+ InventoryItem *item = new ToolItem("WPick", 32000);
+ void* r = player->inventory.addItem("main", item);
+ assert(r == NULL);
+ }
/*{
InventoryItem *item = new MaterialItem(CONTENT_MESE, 6);
void* r = player->inventory.addItem("main", item);
diff --git a/src/tile.cpp b/src/tile.cpp
index 18a2f155a..60e9873c0 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -18,119 +18,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "tile.h"
-#include "porting.h"
+//#include "porting.h"
// For IrrlichtWrapper
-#include "main.h"
-#include
+//#include "main.h"
+//#include
-/*
- These can either be real paths or generated names of preloaded
- textures (like "mud.png_sidegrass")
-*/
-std::string g_tile_texture_paths[TILES_COUNT];
-
-const char * tile_texture_path_get(u32 i)
-{
- assert(i < TILES_COUNT);
-
- //return g_tile_texture_paths[i];
- return g_tile_texture_paths[i].c_str();
-}
-
-// A mapping from tiles to materials
-// Initialized at run-time.
-video::SMaterial g_tile_materials[TILES_COUNT];
-
-enum TileTextureModID
-{
- TTMID_NONE,
- TTMID_SIDEGRASS,
-};
-
-struct TileTextureSpec
-{
- const char *filename;
- enum TileTextureModID mod;
-};
-
-/*
- Initializes g_tile_texture_paths with paths of textures,
- generates generated textures and creates the tile material array.
-*/
-void init_tile_textures()
-{
- TileTextureSpec tile_texture_specs[TILES_COUNT] =
- {
- {NULL, TTMID_NONE},
- {"stone.png", TTMID_NONE},
- {"water.png", TTMID_NONE},
- {"grass.png", TTMID_NONE},
- {"tree.png", TTMID_NONE},
- {"leaves.png", TTMID_NONE},
- {"grass_footsteps.png", TTMID_NONE},
- {"mese.png", TTMID_NONE},
- {"mud.png", TTMID_NONE},
- {"tree_top.png", TTMID_NONE},
- {"mud.png", TTMID_SIDEGRASS},
- {"cloud.png", TTMID_NONE},
- {"coalstone.png", TTMID_NONE},
- {"wood.png", TTMID_NONE},
- };
-
- for(s32 i=0; igetTexture(TextureSpec(path + mod_postfix,
- path, mod));
- }
- g_tile_texture_paths[i] = path + mod_postfix;
- }
- }
-
- for(s32 i=0; igetTexture(path);
- assert(t != NULL);
- }
-
- g_tile_materials[i].Lighting = false;
- g_tile_materials[i].BackfaceCulling = false;
- g_tile_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);
- g_tile_materials[i].setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
- //if(i != TILE_WATER)
- g_tile_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
-
- //g_tile_materials[i].setFlag(video::EMF_TEXTURE_WRAP, video::ETC_REPEAT);
- //g_tile_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);
-
- g_tile_materials[i].setTexture(0, t);
- }
-
- g_tile_materials[TILE_WATER].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
- //g_tile_materials[TILE_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
-}
-
-video::SMaterial & tile_material_get(u32 i)
-{
- assert(i < TILES_COUNT);
-
- return g_tile_materials[i];
-}
+// Nothing here
diff --git a/src/tile.h b/src/tile.h
index 5869c03ee..b903d92a8 100644
--- a/src/tile.h
+++ b/src/tile.h
@@ -21,88 +21,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define TILE_HEADER
#include "common_irrlicht.h"
-#include "utility.h"
-
-// TileID is supposed to be stored in a u16
-
-enum TileID
-{
- TILE_NONE, // Nothing shown
- TILE_STONE,
- TILE_WATER,
- TILE_GRASS,
- TILE_TREE,
- TILE_LEAVES,
- TILE_GRASS_FOOTSTEPS,
- TILE_MESE,
- TILE_MUD,
- TILE_TREE_TOP,
- TILE_MUD_WITH_GRASS,
- TILE_CLOUD,
- TILE_COALSTONE,
- TILE_WOOD,
-
- // Count of tile ids
- TILES_COUNT
-};
-
-enum TileSpecialFeature
-{
- TILEFEAT_NONE,
- TILEFEAT_CRACK,
-};
-
-struct TileCrackParam
-{
- bool operator==(TileCrackParam &other)
- {
- return progression == other.progression;
- }
-
- u16 progression;
-};
+//#include "utility.h"
+#include
struct TileSpec
{
- TileSpec()
+ TileSpec():
+ alpha(255)
+ {
+ }
+
+ TileSpec(const std::string &a_name):
+ name(a_name),
+ alpha(255)
+ {
+ }
+
+ TileSpec(const char *a_name):
+ name(a_name),
+ alpha(255)
{
- id = TILE_NONE;
- feature = TILEFEAT_NONE;
}
bool operator==(TileSpec &other)
{
- if(id != other.id)
- return false;
- if(feature != other.feature)
- return false;
- if(feature == TILEFEAT_NONE)
- return true;
- if(feature == TILEFEAT_CRACK)
- {
- return param.crack == other.param.crack;
- }
- // Invalid feature
- assert(0);
- return false;
+ return (name == other.name && alpha == other.alpha);
}
-
- u16 id; // Id in g_tile_materials, TILE_NONE=none
- enum TileSpecialFeature feature;
- union
- {
- TileCrackParam crack;
- } param;
+
+ // path + mods
+ std::string name;
+ u8 alpha;
};
-/*
- Functions
-*/
-
-void init_tile_textures();
-
-const char * tile_texture_path_get(u32 i);
-
-video::SMaterial & tile_material_get(u32 i);
-
#endif
diff --git a/src/utility.cpp b/src/utility.cpp
index 8befaaeec..65615f9c9 100644
--- a/src/utility.cpp
+++ b/src/utility.cpp
@@ -88,6 +88,41 @@ const v3s16 g_26dirs[26] =
// 26
};
+const v3s16 g_27dirs[27] =
+{
+ // +right, +top, +back
+ v3s16( 0, 0, 1), // back
+ v3s16( 0, 1, 0), // top
+ v3s16( 1, 0, 0), // right
+ v3s16( 0, 0,-1), // front
+ v3s16( 0,-1, 0), // bottom
+ v3s16(-1, 0, 0), // left
+ // 6
+ v3s16(-1, 1, 0), // top left
+ v3s16( 1, 1, 0), // top right
+ v3s16( 0, 1, 1), // top back
+ v3s16( 0, 1,-1), // top front
+ v3s16(-1, 0, 1), // back left
+ v3s16( 1, 0, 1), // back right
+ v3s16(-1, 0,-1), // front left
+ v3s16( 1, 0,-1), // front right
+ v3s16(-1,-1, 0), // bottom left
+ v3s16( 1,-1, 0), // bottom right
+ v3s16( 0,-1, 1), // bottom back
+ v3s16( 0,-1,-1), // bottom front
+ // 18
+ v3s16(-1, 1, 1), // top back-left
+ v3s16( 1, 1, 1), // top back-right
+ v3s16(-1, 1,-1), // top front-left
+ v3s16( 1, 1,-1), // top front-right
+ v3s16(-1,-1, 1), // bottom back-left
+ v3s16( 1,-1, 1), // bottom back-right
+ v3s16(-1,-1,-1), // bottom front-left
+ v3s16( 1,-1,-1), // bottom front-right
+ // 26
+ v3s16(0,0,0),
+};
+
static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
diff --git a/src/utility.h b/src/utility.h
index fd2881cff..785ff167c 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -36,6 +36,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
extern const v3s16 g_26dirs[26];
+// 26th is (0,0,0)
+extern const v3s16 g_27dirs[27];
+
inline void writeU32(u8 *data, u32 i)
{
data[0] = ((i>>24)&0xff);
@@ -666,6 +669,14 @@ inline s32 stoi(std::string s)
return atoi(s.c_str());
}
+inline float stof(std::string s)
+{
+ float f;
+ std::istringstream ss(s);
+ ss>>f;
+ return f;
+}
+
inline std::string itos(s32 i)
{
std::ostringstream o;
diff --git a/src/voxel.cpp b/src/voxel.cpp
index 272e11ccc..d68a8db02 100644
--- a/src/voxel.cpp
+++ b/src/voxel.cpp
@@ -110,7 +110,7 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
if(pr <= 9)
c = pr + '0';
}
- else if(liquid_replaces_content(m))
+ else if(m == CONTENT_AIR)
{
c = ' ';
}
@@ -653,637 +653,4 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
}
#endif
-#if 0
-int VoxelManipulator::getWaterPressure(v3s16 p, s16 &highest_y, int recur_count)
-{
- m_flags[m_area.index(p)] |= VOXELFLAG_CHECKED2;
-
- if(p.Y > highest_y)
- highest_y = p.Y;
-
- /*if(recur_count > 1000)
- throw ProcessingLimitException
- ("getWaterPressure recur_count limit reached");*/
-
- if(recur_count > 10000)
- return -1;
-
- recur_count++;
-
- v3s16 dirs[6] = {
- v3s16(0,1,0), // top
- v3s16(0,0,1), // back
- v3s16(0,0,-1), // front
- v3s16(1,0,0), // right
- v3s16(-1,0,0), // left
- v3s16(0,-1,0), // bottom
- };
-
- // Load neighboring nodes
- emerge(VoxelArea(p - v3s16(1,1,1), p + v3s16(1,1,1)), 1);
-
- s32 i;
- for(i=0; i<6; i++)
- {
- v3s16 p2 = p + dirs[i];
- u8 f = m_flags[m_area.index(p2)];
- // Ignore inexistent or checked nodes
- if(f & (VOXELFLAG_INEXISTENT | VOXELFLAG_CHECKED2))
- continue;
- MapNode &n = m_data[m_area.index(p2)];
- // Ignore non-liquid nodes
- if(content_liquid(n.d) == false)
- continue;
-
- int pr;
-
- // If at ocean surface
- if(n.pressure == 1 && n.d == CONTENT_WATERSOURCE)
- //if(n.pressure == 1) // Causes glitches but is fast
- {
- pr = 1;
- }
- // Otherwise recurse more
- else
- {
- pr = getWaterPressure(p2, highest_y, recur_count);
- if(pr == -1)
- continue;
- }
-
- // If block is at top, pressure here is one higher
- if(i == 0)
- {
- if(pr < 255)
- pr++;
- }
- // If block is at bottom, pressure here is one lower
- else if(i == 5)
- {
- if(pr > 1)
- pr--;
- }
-
- // Node is on the pressure route
- m_flags[m_area.index(p)] |= VOXELFLAG_CHECKED4;
-
- // Got pressure
- return pr;
- }
-
- // Nothing useful found
- return -1;
-}
-
-void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
- VoxelArea request_area,
- core::map &active_nodes,
- int recur_count)
-{
- //if(recur_count > 10000)
- /*throw ProcessingLimitException
- ("spreadWaterPressure recur_count limit reached");*/
- if(recur_count > 10)
- return;
- recur_count++;
-
- /*dstream<<"spreadWaterPressure: p=("
- < 255)
- pr = 255;
-
- /*dstream<<"WARNING: Pressure at ("
- < &active_nodes,
- int recursion_depth, bool debugprint,
- u32 stoptime)
-{
- v3s16 dirs[6] = {
- v3s16(0,1,0), // top
- v3s16(0,0,-1), // front
- v3s16(0,0,1), // back
- v3s16(-1,0,0), // left
- v3s16(1,0,0), // right
- v3s16(0,-1,0), // bottom
- };
-
- recursion_depth++;
-
- v3s16 p;
- bool from_ocean = false;
-
- // Randomize horizontal order
- static s32 cs = 0;
- if(cs < 3)
- cs++;
- else
- cs = 0;
- s16 s1 = (cs & 1) ? 1 : -1;
- s16 s2 = (cs & 2) ? 1 : -1;
- //dstream<<"s1="<= PRESERVE_WATER_VOLUME ? 3 : 2)
- if(n.pressure >= 3)
- break;
- continue;
- }
- // Else block is at some side. Select it if it has enough pressure
- //if(n.pressure >= PRESERVE_WATER_VOLUME ? 2 : 1)
- if(n.pressure >= 2)
- {
- break;
- }
- }
-
- // If there is nothing to move, return
- if(i==6)
- return false;
-
- /*
- Move water and bubble
- */
-
- u8 m = m_data[m_area.index(p)].d;
- u8 f = m_flags[m_area.index(p)];
-
- if(m == CONTENT_WATERSOURCE)
- from_ocean = true;
-
- // Move air bubble if not taking water from ocean
- if(from_ocean == false)
- {
- m_data[m_area.index(p)].d = m_data[m_area.index(removed_pos)].d;
- m_flags[m_area.index(p)] = m_flags[m_area.index(removed_pos)];
- }
-
- /*
- This has to be done to copy the brightness of a light source
- correctly. Otherwise unspreadLight will fuck up when water
- has replaced a light source.
- */
- u8 light = m_data[m_area.index(removed_pos)].getLightBanksWithSource();
-
- m_data[m_area.index(removed_pos)].d = m;
- m_flags[m_area.index(removed_pos)] = f;
-
- m_data[m_area.index(removed_pos)].setLightBanks(light);
-
- // Mark removed_pos checked
- m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;
-
- // If block was dropped from surface, increase pressure
- if(i == 0 && m_data[m_area.index(removed_pos)].pressure == 1)
- {
- m_data[m_area.index(removed_pos)].pressure = 2;
- }
-
- /*
- NOTE: This does not work as-is
- if(m == CONTENT_WATERSOURCE)
- {
- // If block was raised to surface, increase pressure of
- // source node
- if(i == 5 && m_data[m_area.index(p)].pressure == 1)
- {
- m_data[m_area.index(p)].pressure = 2;
- }
- }*/
-
- /*if(debugprint)
- {
- dstream<<"VoxelManipulator::flowWater(): Moved bubble:"<= stoptime || overflow)
- {
- dstream<<"flowWater: stoptime reached"<=0; i--)
- {
- // Don't try to flow to top
- if(m_disable_water_climb && i == 0)
- continue;
-
- //v3s16 p = removed_pos + dirs[i];
- p = removed_pos + v3s16(s1*dirs[i].X, dirs[i].Y, s2*dirs[i].Z);
-
- u8 f = m_flags[m_area.index(p)];
- // Water can't move to inexistent nodes
- if(f & VOXELFLAG_INEXISTENT)
- continue;
- MapNode &n = m_data[m_area.index(p)];
- // Water can only move to air
- if(liquid_replaces_content(n.d) == false)
- continue;
-
- // Flow water to node
- bool moved =
- flowWater(p, active_nodes, recursion_depth,
- debugprint, stoptime);
- /*flowWater(p, active_nodes, recursion_depth,
- debugprint, counter, counterlimit);*/
-
- if(moved)
- {
- // Search again from all neighbors
- goto find_again;
- }
- }
-
- return true;
-}
-
-void VoxelManipulator::flowWater(
- core::map &active_nodes,
- int recursion_depth, bool debugprint,
- u32 timelimit)
-{
- addarea_time = 0;
- emerge_time = 0;
- emerge_load_time = 0;
- clearflag_time = 0;
- updateareawaterpressure_time = 0;
- flowwater_pre_time = 0;
-
- if(active_nodes.size() == 0)
- {
- dstream<<"flowWater: no active nodes"<::Node
- *n = active_nodes.getIterator().getNode();
-#endif
-
-#if 1
-
- core::map::Iterator
- i = active_nodes.getIterator().getNode();
- for(s32 j=0; j::Node *n = i.getNode();
-
- // Decrement index if less than 0.
- // This keeps us in existing indices always.
- if(k > 0)
- k--;
-#endif
-
- v3s16 p = n->getKey();
- active_nodes.remove(p);
- flowWater(p, active_nodes, recursion_depth,
- debugprint, stoptime);
- }
-
- }
- catch(ProcessingLimitException &e)
- {
- //dstream<<"getWaterPressure ProcessingLimitException"< & from_nodes);
-#if 0
- // VOXELFLAG_CHECKED2s must usually be cleared before calling
- // -1: dead end, 0-255: pressure
- // highest_y: Highest found water y is stored here.
- // Must be initialized to -32768
- int getWaterPressure(v3s16 p, s16 &highest_y, int recur_count);
-
- /*
- VOXELFLAG_CHECKED3s must usually be cleared before calling.
-
- active_nodes: surface-touching air nodes with flow-causing
- pressure. set-like dummy map container.
-
- Spreads pressure pr at node p to request_area or as far as
- there is invalid pressure.
- */
- void spreadWaterPressure(v3s16 p, int pr,
- VoxelArea request_area,
- core::map &active_nodes,
- int recur_count);
-
- /*
- VOXELFLAG_CHECKED3s must usually be cleared before calling.
- */
- void updateAreaWaterPressure(VoxelArea a,
- core::map &active_nodes,
- bool checked3_is_clear=false);
-
- /*
- Returns true if moved something
- */
- bool flowWater(v3s16 removed_pos,
- core::map &active_nodes,
- int recursion_depth=0,
- bool debugprint=false,
- u32 stoptime=0
- );
-
- /*
- To flow some water, call this with the target node in
- active_nodes
- TODO: Make the active_nodes map to contain some vectors
- that are properly sorted according to water flow order.
- The current order makes water flow strangely if the
- first one is always taken.
- No, active_nodes should preserve the order stuff is
- added to it, in addition to adhering the water flow
- order.
- */
- void flowWater(core::map &active_nodes,
- int recursion_depth=0,
- bool debugprint=false,
- u32 timelimit=50
- );
-#endif
-
/*
Virtual functions
*/