From 626ed6338aa90eb07038adee29643e692fec6545 Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Tue, 14 Dec 2010 00:21:18 +0200
Subject: [PATCH] in before messing with face drawing orientation

---
 Makefile         |   2 +-
 data/mud.png     | Bin 831 -> 1586 bytes
 data/tree.png    | Bin 873 -> 1445 bytes
 src/client.cpp   |  13 ++--
 src/client.h     |   6 +-
 src/inventory.h  |   3 +-
 src/main.cpp     |  38 +++++----
 src/main.h       |   4 +-
 src/map.cpp      | 196 +----------------------------------------------
 src/map.h        |   8 +-
 src/mapblock.cpp |  44 ++++++++---
 src/mapblock.h   |   3 +-
 src/mapnode.h    |  77 +++++++++++--------
 src/test.cpp     |   7 +-
 src/utility.h    |   9 ++-
 15 files changed, 133 insertions(+), 277 deletions(-)

diff --git a/Makefile b/Makefile
index 2b4e8dda3..3985bdbc5 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # It's usually sufficient to change just the target name and source file list
 # and be sure that CXX is set to a valid compiler
 TARGET = test
-SOURCE_FILES = voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp
+SOURCE_FILES = mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp
 SOURCES = $(addprefix src/, $(SOURCE_FILES))
 OBJECTS = $(SOURCES:.cpp=.o)
 FASTTARGET = fasttest
diff --git a/data/mud.png b/data/mud.png
index 0c6925d3bcfa8d977af9535bdc3c8590f99b9a97..7cb9c89a637584b4e53c82a7c6eb1ec7109befae 100644
GIT binary patch
literal 1586
zcmZuw2~d+q6kb75sRsk0q?k5{zaXLY3W9(a3WY_b(ZE<K9v~t$tWxFZXs}g_qP0L4
zTC5rBK?NNOYAQ<*7(^Tn3sP(GV5=Y_0#ZZ-u?1zj!5IgnJF~m*{qx>_-}~PC4=Mb-
zCz@KD0stmLAJ5hNHZ$yTM*K|HggXOZ3=}K;y|~K;HygYd_n2W(N(mttV}uZdP!I$P
z00964fB=912s~@VCrSY!0Aqj<fDj1(7eoOifM9?TKoCHIzceCkBs?R8VoVUi5F$Zf
z7*m7@gqYh1Q3we)Af)`{R2e0dV1f}w5J3S7gb_?JA_!tAAOSOsD1rnESU?Ox$|D5G
zpfH$E>04-!kfDGG<2RUGpVzRQivgMAj}(tFLMbMMCqjgH1f~=b0x{+`qLjbS4M-_J
z1vY{`BaC875Wx^5&KEO^D1ij?IuN6f5?&u<l-F&@9uCHp8H&dRd;`gw`x=!~;lP9N
zBa{QfmE-QvQVdOIm{5cXL|A|b2=pzj0Vg^{Zh#1VD+6M}5T+3E9$+A#;pG};1T%st
zhJ<$x0>tYaJ`E5I?++&lC<X)p9?k%v026>PA6vozrkn!cK!dARW;7ZAqYmil;Xk8x
zOex()Ljl;>&o<e|NLpI$vhPWbEi07RO^;8=J!9ixlJM=yaobGHn=a@*nx@|oX3CB_
zl?QGV&?O;krS@vgjhG<!E?2d*?|I7?6P9J+l*;Rodq1Ooc577|7E>tgTV{MB@<Hmk
zy2q|c^St{x8u5Z%vnH>b^GU|kY#+M@6QhfTqKscG$EO}~h?Y0SX~b!+=X-vW2P^CC
zOE1gUWNA;A{T|`yqmErDI$N!&=)c?jWchZ_!nMl>&VLnMmSVE1;auPn<I&q2PGznM
zxVXgkz4V8&$pHbId-Wz;zN^S@aFV4wdhYC%WUp15cXWeCy#b^s?rz<_4^|h5JF}Wp
zU7aOA9Zy6rKhn*A)to2`NI0R8Jz40!JI~#CcFntHE<OKbOT%13^z{~@);i#QCq3ep
zL>n|(q-;%E9DAfn*VT5@WtYVs_RuFy`_69T&H;7zq$%~PLRE~nZ{ai_oo0qY?o}pv
zkx_0ntu5BM^m2$(uI=?IY4OK7d;Vx^iKuUnpIhX(Q?OX->^C>e_eEm+nW#%geM*X3
zOHoAh%n6^m_38d?NK2AgJM`c5v<w+IGtX*&i&aL}@juJ=-=6yS-qPCOzYbK?IhhB=
zw;jEt31r~|V*LUOQndG^Y2~xt3$@+KUkmb6^5X7~(N}w`&ZmZ+a!Ss!X&U9P$P6kr
zI~1!qsnfl>a@ghJwKDMqkkYKL6vbCr9@%nFQnfi|&H}rRuSHf>1##()ElxLbrMJId
zpVWIcqWS5hyFCZ5_|9(3mo~82t0k>9i@%W^D{WTTtUK&jvi`KGJSuF}X1pZ4Lf6^<
zV{gGVrQ1uJ<xg)%Cf(a%7WebGkc!VIZm`@s);ZB#zv#gzO%8Eay9c*FoB#g$vKKoq
zM$L0or+V1lStw63vl34t&Y2(1Djpl4EJ~l?rghj;cT0J2{OT2DWAjAX&|5z=%8SnR
z+cxVR#gRGTTV3SRMulq1fy2p*%r{*YovdzV)?e;WJ$7*DGW-G1%g-}+>BfEk0s5W!
A1poj5

delta 809
zcmV+^1J?Yq48I1DBYyw`b3#c}2nYz<;ZNWI000SaNLh0L01FZT01FZU(%pXi0008w
zNkl<ZD3Jxh+iu!s003Z{-v^AbO~3(6aDstAAXU_msp%oDGHtBAS*7-3+UxBBcDr5l
zs!gR<OV%n)7E%I)LmU#o7@zQu4|v~)9`0@97*KRmh$HSix_|IosZhRb{F^IPX~Oqi
zBAH2?onJu1b4}I9NU*zI30x>d8H!9XG-S9K)bv%Ji6=6a;r097XnZBNxn*mk=4evR
zXG1n>YEuiM7#DT<joRRLnA$8;eD1h$Ohv%Nnz1o<(i;FDJgn|40}t>RZ3PPsA-MJA
zq}$JyOZME6Dt~!=s*F_a*$=y&W-psee{c6Hn;WN%E0E>!VzqdAEz<-wY{^AY)b0jH
z?~aVXHxTXphx7FZB?9xRTU+l>KG8M~(!zRx5^sO|{Z7753#bBpIzbZzlgmrfk&)sU
zDb4@!=ii1htH1iSr*y!ZU+TtKp8JkHx@q32re`UA^?&+yc-iXAG(*e@Q(Z^><&X9H
zP`(mUDX<n#EqwRm@t1?W$6s3wE{KvO0g*)^m5N6r2u_pG*?F;N4sXVz$<gP30Oc=R
zgU)J<KRG+EA3k3KXLT)}!5EeetCoB5z5V*|u-|HOoS+QGkyseiwn{h!I5xKM?DLCj
zZY6Sh+JEGzs4}<3iddlHe|`CsUzb88Zo=_KrhxujtC0k9KQ%FA=>{-D5*!_yz{$cv
zxKIQlZe?5YR9}N;P7r(jF5r1u;F7s)GQxm(I3Xmnx?&f~1$|~ddH!^GbxmPtac5_N
zEC)9?>PQ1G_a8L}ozrfoz-C#2MPpPxpKYDA#eW0|)p=$!jRVs2Jds^(v<DXHV3ww9
zx>FQ3R9nAo-_30ldei-fPhH0fe7D~j7j_?9oP9H^5D9y0Bm+vB^u0VfIH-{<#f6iI
ztKv9L2O)JfllCgwM3H-4s5_0T+uDBFv%~1ypI+c-2!z})9{H~)uV5jM1T4Wwk~p@Y
nB_ekWI7e`5f#4*-r~vsNW#Dn!vKTEv00000NkvXXu0mjfwF7(u

diff --git a/data/tree.png b/data/tree.png
index 98f6f54ddce147c4b2f8805f97f28d7bc1e72542..65abfc243e868f5e03a058bdd26ab473adae4f6d 100644
GIT binary patch
literal 1445
zcmZux4NR6*6u$f|q)?U+NQQwg0WvcXnUSc-j~*i+#D+gHXb$*-1ENSkn#Hj4o8#vc
ztSL(BfQ1Rz=z>y!k`ihBm_+Q>vZZ|i3Pg-#K)3th=J@Gu_ug~fopYb(Jm>5^8WFbH
z+RD+2F=h>0f+E#zW89Xe>MSTs^kvM9MTABLD_2f$IekgxN#hbiaL$Pc5dlEcG{G2W
zj2J`4fH6&F&HE$-<D3yOL<YdL{|gdKaK?!dG6V*idTCzTe0a&ZAmWGwfSM+W1R@6@
zWg`jzt_%R7PDND;E;w;QLO{?!<C2pg<Ol>BY9t8-0tbyWln6paXdpqG&KF`18gM=n
z5Q!dPDt#WpDlSH3g+E_BDY+2Dxk>~?6+uEE=Rl-v6hghP3=l${nw-a8aw$k~<OGC@
zFG+!d11D7nN&$ka`alX*w=sJ*m{MjYo)Yj8q-yR%R7FJrPs7hsj?Gq1xid>KHdzuE
zNF0zfK&FW~S~Ep-hTIIfn3Dm-C6WMCJs_sx>~f7WLXx8(;Hq=LP}Mnm8i392k0Qwg
zF^)`yOU4Bw&XCmDa>+<23QPe_uZ|U_=8T!fLQp`Idxynkks^E@SnP;lN9~>HjHJif
zuKK1oziZOaw|KNFyr#z~!@oAM@XNHb(O-OK=HWDP=)q9_VatyiFIwpTePzKpL)%X+
zgWo6hpO4e+%nn^YIX>J`VKDo3cc<m=_hOd*?6GjyXl<xv+fZG7_Og|mgAT%b`larE
zt5P;*H5piupHpvn<WPR4w#a!X9ES(;3d-Xfw(M`NyFT*NHnAh=ai7BOBWd9&1ulzM
zFU-=Hy4fe+Yd>_fY}u7$s!#RY-fWw>)}zvX%6-Ujyz2Buhp+%I$BTak_Bv&(xoo(Q
z`e5WctA>^rLTliO@wU5}**&+S?alLx{0v1^!#%6cyZz-|yjAbt8yy}yHu(09xVuwL
z%lF7XJ~{QAr)}Rv;+cVxu9Actoh@D;^i}_ew=%|lwBDcE*83sqyaHC*)0Q&b%ioMe
z)S2$yq^t3D$sF_Odh^@Kzccaa43mZ~ha~Uz@{q&>r(*6;oqckne@py@*ubE?c#%*V
zvaRtQzd+lQOTrGI_dsfj>9wfU@t(Y<!fu_<@iedZk2$*~SI3M;UNS`YkDe=Tow(%k
zTTo>dr0q@Iw72u)1qt@xy1d|U`Y(I#cjxv+YMVFQ81cF7+LWt{@rPZe6+5eATGyrQ
zD|h|+*!rvunQl5t4fYM_c6hP<V7ABplU}t=%Wm~sI=_0e)4A+Uq0P1N2z|+<zOZ!I
z?&fQK0~W96968bCdUa9B^A=@hKh)=jST?`3<O7>xUDTC*&N00!*8I~Lk@6L+?fKj)
z{lx9KYIBo)Z?qgw%=^^g%xKi<)arq>)@Svl!&|fMGM?GK$T)Nm92QiyDK_UniaxM?

delta 851
zcmV-Z1FZa|3+V=sBYyx1a7bBm000ie000ie0hKEb8vp<U8%ab#R49=F5CiZ00jZN=
z`0nxA;^qMT0|*5OFf1n8*W6K0ImOJ{6c-Zh>h2#R9j&^-x4+mzJTFEzA^|WR2uwmY
z`2O`JAr+RM&wO$~$kovE?F0x12J-Ruu)x|C7zB%YTI=)f^MBd^zS6=1Yj923+36q`
z91<5478M4(ztrpH`QYH`E+ilY1OpZn|42F{{q_ERgR-i`x@}=m12!QSR!=(P=j%*T
zHxdK;#?s<PIV=SS`~U_29~>DH4hh4;+WP(bRZ%t5*5b;}+5@+vcI@cs=j-jKp|?0R
zD;5wE)8FX({eSoB?Dn&}%QY}1-|FY!;^<9BF&+;dEF>2K#;(E3%)M1ZHGXDK-RJH>
zI3)A&`5g`%Gbb$X^7|?y6(%7U^!Ntu?Dya5;PLtU1LyShLM|)0*V*ms`z|LL)!pp0
zxy)r>LvfC(UQ9PwTu8FD&mId2=K1~$1Q;405Cj1X1b?f)$@l>ZzUa|l2TB6;>*4kK
z?cwn1?)bdK(yzP56cP+JF(f)XE(HJe*yHB|^Xl$ON;&B1@6+1oJ~b&gI4=?i0{sg2
zS3^G-8VN~6IAu~w*5BV96(63Zwej}!0u>JmHzOQnRX_&>0U8kvy1>dABo*!3=zf&0
zlA^x!?0@u6YJ@*EAiu`JEhQue2mAvO3<D`68hn?uc3?s$9UW?jsLsRLAR!oSSUv_6
z1rr4T6%`r;2MxHmzf(*_8w3yoyP0gh&e_n==Elv~9T*Mx0|MIO>KG6Rk*ddeSU%_S
z{-w0aYhOD1`2W`5-wy*60{j01H6bV>90(Q^3xD(c{<^=~E*b;P-|0X(E8OGm$I8+`
zIx=8tnF0X@p0n8f7WV@a4+HcD{sQ^>6cq?59395e*+DZY%Gl-y3H}EH`tS7n_5AW_
zTs`yi|NRH^Hz6DYk9kz@<n!?P_cJ6N4-5_c`u##f92yiF6&?@y?))tt7xwxH7ZD2Y
z?M(0M=IE!u;R3t9&eGc1^Y;C9jkz@_CKU|?eU-Z^BNXT0;Q9dmuExx!zR5W<DA3v6
dUsXqBPbkO+e-?}=Y;*ts002ovPDHLkV1kqmlBxgz

diff --git a/src/client.cpp b/src/client.cpp
index 2471558f8..bfec8b730 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -68,11 +68,10 @@ void * ClientUpdateThread::Thread()
 	return NULL;
 }
 
-Client::Client(IrrlichtDevice *device, video::SMaterial *materials,
-		float delete_unused_sectors_timeout,
+Client::Client(IrrlichtDevice *device,
 		const char *playername):
 	m_thread(this),
-	m_env(new ClientMap(this, materials,
+	m_env(new ClientMap(this,
 			device->getSceneManager()->getRootSceneNode(),
 			device->getSceneManager(), 666),
 			dout_client),
@@ -82,7 +81,6 @@ Client::Client(IrrlichtDevice *device, video::SMaterial *materials,
 	camera_direction(0,0,1),
 	m_server_ser_ver(SER_FMT_VER_INVALID),
 	m_step_dtime(0.0),
-	m_delete_unused_sectors_timeout(delete_unused_sectors_timeout),
 	m_inventory_updated(false)
 {
 	//m_fetchblock_mutex.Init();
@@ -193,15 +191,18 @@ void Client::step(float dtime)
 			JMutexAutoLock lock(m_env_mutex);
 
 			core::list<v3s16> deleted_blocks;
+
+			float delete_unused_sectors_timeout = 
+				g_settings.getFloat("client_delete_unused_sectors_timeout");
 	
 			// Delete sector blocks
 			/*u32 num = m_env.getMap().deleteUnusedSectors
-					(m_delete_unused_sectors_timeout,
+					(delete_unused_sectors_timeout,
 					true, &deleted_blocks);*/
 			
 			// Delete whole sectors
 			u32 num = m_env.getMap().deleteUnusedSectors
-					(m_delete_unused_sectors_timeout,
+					(delete_unused_sectors_timeout,
 					false, &deleted_blocks);
 
 			if(num > 0)
diff --git a/src/client.h b/src/client.h
index 65b02a0e2..3789f4cbe 100644
--- a/src/client.h
+++ b/src/client.h
@@ -152,9 +152,7 @@ class Client : public con::PeerHandler
 	/*
 		NOTE: Every public method should be thread-safe
 	*/
-	Client(IrrlichtDevice *device, video::SMaterial *materials,
-			float delete_unused_sectors_timeout,
-			const char *playername);
+	Client(IrrlichtDevice *device, const char *playername);
 	~Client();
 	/*
 		The name of the local player should already be set when
@@ -280,8 +278,6 @@ class Client : public con::PeerHandler
 	float m_step_dtime;
 	JMutex m_step_dtime_mutex;
 
-	float m_delete_unused_sectors_timeout;
-	
 	// This is behind m_env_mutex.
 	bool m_inventory_updated;
 
diff --git a/src/inventory.h b/src/inventory.h
index cc6393d43..1fab9d027 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -86,7 +86,8 @@ class MaterialItem : public InventoryItem
 	}
 	video::ITexture * getImage()
 	{
-		return g_materials[m_material].getTexture(0);
+		u16 tile = content_tile(m_material, v3s16(1,0,0));
+		return g_tile_materials[tile].getTexture(0);
 	}
 	std::string getText()
 	{
diff --git a/src/main.cpp b/src/main.cpp
index b1d88090c..49973e99c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -253,7 +253,7 @@ TODO: A mapper to map contents to tile names (for each side)
 
 IrrlichtDevice *g_device = NULL;
 
-const char *g_content_filenames[MATERIALS_COUNT] =
+/*const char *g_content_filenames[MATERIALS_COUNT] =
 {
 	"../data/stone.png",
 	"../data/grass.png",
@@ -268,7 +268,7 @@ const char *g_content_filenames[MATERIALS_COUNT] =
 };
 
 // Material cache
-video::SMaterial g_materials[MATERIALS_COUNT];
+video::SMaterial g_materials[MATERIALS_COUNT];*/
 
 // Texture cache
 TextureCache g_texturecache;
@@ -1293,7 +1293,7 @@ int main(int argc, char *argv[])
 		Initialize material array
 	*/
 
-	//video::SMaterial g_materials[MATERIALS_COUNT];
+	/*//video::SMaterial g_materials[MATERIALS_COUNT];
 	for(u16 i=0; i<MATERIALS_COUNT; i++)
 	{
 		g_materials[i].Lighting = false;
@@ -1318,6 +1318,7 @@ int main(int argc, char *argv[])
 	g_materials[CONTENT_WATER].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
 	//g_materials[CONTENT_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
 	g_materials[CONTENT_OCEAN].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
+	*/
 
 	/*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));
 	g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));
@@ -1337,6 +1338,23 @@ int main(int argc, char *argv[])
 	g_texturecache.set("torch", driver->getTexture("../data/torch.png"));
 	g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));
 	g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));
+	
+	/*
+		Load tile textures
+	*/
+	for(s32 i=0; i<TILES_COUNT; i++)
+	{
+		if(g_tile_texture_names[i] == NULL)
+			continue;
+		std::string name = g_tile_texture_names[i];
+		std::string filename;
+		filename += "../data/";
+		filename += name;
+		filename += ".png";
+		g_texturecache.set(name, driver->getTexture(filename.c_str()));
+	}
+
+	tile_materials_preload(g_texturecache);
 
 	/*
 		Make a scope here for the client so that it gets removed
@@ -1359,10 +1377,7 @@ int main(int argc, char *argv[])
 		Create client
 	*/
 
-	// TODO: Get rid of the g_materials parameter or it's globalness
-	Client client(device, g_materials,
-			g_settings.getFloat("client_delete_unused_sectors_timeout"),
-			playername);
+	Client client(device, playername);
 	
 	Address connect_address(0,0,0,0, port);
 	try{
@@ -1396,19 +1411,14 @@ int main(int argc, char *argv[])
 	/*
 		Create skybox
 	*/
-	scene::ISceneNode* skybox = smgr->addSkyBoxSceneNode(
+	scene::ISceneNode* skybox;
+	skybox = smgr->addSkyBoxSceneNode(
 		driver->getTexture("../data/skybox2.png"),
 		driver->getTexture("../data/skybox3.png"),
 		driver->getTexture("../data/skybox1.png"),
 		driver->getTexture("../data/skybox1.png"),
 		driver->getTexture("../data/skybox1.png"),
 		driver->getTexture("../data/skybox1.png"));
-	/*	driver->getTexture("../data/irrlicht2_up.jpg"),
-		driver->getTexture("../data/irrlicht2_dn.jpg"),
-		driver->getTexture("../data/irrlicht2_lf.jpg"),
-		driver->getTexture("../data/irrlicht2_rt.jpg"),
-		driver->getTexture("../data/irrlicht2_ft.jpg"),
-		driver->getTexture("../data/irrlicht2_bk.jpg"));*/
 	
 	/*
 		Create the camera node
diff --git a/src/main.h b/src/main.h
index 3d676bd43..6a4b5a090 100644
--- a/src/main.h
+++ b/src/main.h
@@ -53,8 +53,8 @@ extern std::ostream *derr_server_ptr;
 
 // TODO: Move somewhere else? materials.h?
 // This header is only for MATERIALS_COUNT
-#include "mapnode.h"
-extern video::SMaterial g_materials[MATERIALS_COUNT];
+//#include "mapnode.h"
+//extern video::SMaterial g_materials[MATERIALS_COUNT];
 
 #include "utility.h"
 extern TextureCache g_texturecache;
diff --git a/src/map.cpp b/src/map.cpp
index f9adbd00a..213404a07 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1504,7 +1504,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
 		sector->setHeightmap(p_in_sector, hm);
 
 		//TODO: Make these values configurable
-		hm->generateContinued(0.0, 0.0, corners);
+		//hm->generateContinued(0.0, 0.0, corners);
+		hm->generateContinued(0.5, 0.2, corners);
 		//hm->generateContinued(1.0, 0.2, corners);
 		//hm->generateContinued(2.0, 0.2, corners);
 
@@ -2755,7 +2756,6 @@ void ServerMap::PrintInfo(std::ostream &out)
 
 ClientMap::ClientMap(
 		Client *client,
-		video::SMaterial *materials,
 		scene::ISceneNode* parent,
 		scene::ISceneManager* mgr,
 		s32 id
@@ -2763,7 +2763,6 @@ ClientMap::ClientMap(
 	Map(dout_client),
 	scene::ISceneNode(parent, mgr, id),
 	m_client(client),
-	m_materials(materials),
 	mesh(NULL)
 {
 	/*m_box = core::aabbox3d<f32>(0,0,0,
@@ -2837,8 +2836,7 @@ void ClientMap::deSerializeSector(v2s16 p2d, std::istream &is)
 	sector->deSerialize(is);
 }
 
-void ClientMap::renderMap(video::IVideoDriver* driver,
-	video::SMaterial *materials, s32 pass)
+void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
 {
 	//m_dout<<DTIME<<"Rendering map..."<<std::endl;
 	DSTACK(__FUNCTION_NAME);
@@ -3037,193 +3035,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver,
 
 void ClientMap::updateMesh()
 {
-#if 0
-	DSTACK(__FUNCTION_NAME);
-	//TODO
-	/*
-		Check what sectors don't draw anything useful at ground level
-		and create a mesh of the rough heightmap at those positions.
-	*/
-
-	m_camera_mutex.Lock();
-	v3f camera_position = m_camera_position;
-	v3f camera_direction = m_camera_direction;
-	m_camera_mutex.Unlock();
-
-	v3s16 cam_pos_nodes(
-			camera_position.X / BS,
-			camera_position.Y / BS,
-			camera_position.Z / BS);
-
-	v3s16 box_nodes_d = HEIGHTMAP_RANGE_NODES * v3s16(1,1,1);
-
-	v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
-	v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;
-
-	// Take a fair amount as we will be dropping more out later
-	v3s16 p_blocks_min(
-			p_nodes_min.X / MAP_BLOCKSIZE - 1,
-			p_nodes_min.Y / MAP_BLOCKSIZE - 1,
-			p_nodes_min.Z / MAP_BLOCKSIZE - 1);
-	v3s16 p_blocks_max(
-			p_nodes_max.X / MAP_BLOCKSIZE + 1,
-			p_nodes_max.Y / MAP_BLOCKSIZE + 1,
-			p_nodes_max.Z / MAP_BLOCKSIZE + 1);
-	
-	/*
-		Initialize new mesh
-	*/
-	
-	scene::SMesh *mesh_new = new scene::SMesh();
-	//scene::IMeshBuffer *buf = NULL;
-	scene::SMeshBuffer *buf = NULL;
-
-	u8 material_in_use = 0;
-
-	/*
-		Loop through sectors
-	*/
-	
-	for(core::map<v2s16, MapSector*>::Iterator
-			si = m_sectors.getIterator();
-			si.atEnd() == false; si++)
-	{
-		MapSector *sector = si.getNode()->getValue();
-		
-		if(sector->getId() != MAPSECTOR_CLIENT)
-		{
-			dstream<<"WARNING: Client has a non-client sector"
-					<<std::endl;
-			continue;
-		}
-		
-		ClientMapSector *cs = (ClientMapSector*)sector;
-
-		v2s16 sp = sector->getPos();
-
-		if(sp.X < p_blocks_min.X
-		|| sp.X > p_blocks_max.X
-		|| sp.Y < p_blocks_min.Z
-		|| sp.Y > p_blocks_max.Z)
-			continue;
-		
-		/*
-			Get some ground level info
-		*/
-		
-		s16 a = -5;
-
-		s16 cn[4] = 
-		{
-			cs->getCorner(0)+a,
-			cs->getCorner(1)+a,
-			cs->getCorner(2)+a,
-			cs->getCorner(3)+a,
-		};
-		s16 cn_avg = (cn[0]+cn[1]+cn[2]+cn[3])/4;
-		s16 cn_min = 32767;
-		s16 cn_max = -32768;
-		for(s16 i=0; i<4; i++)
-		{
-			if(cn[i] < cn_min)
-				cn_min = cn[i];
-			if(cn[i] > cn_max)
-				cn_max = cn[i];
-		}
-		s16 cn_slope = cn_max - cn_min;
-		
-		/*
-			Generate this part of the heightmap mesh
-		*/
-
-		u8 material;
-		if(cn_avg + MAP_BLOCKSIZE/4 <= WATER_LEVEL)
-			material = 0;
-		else if(cn_slope <= MAP_BLOCKSIZE)
-			material = 1;
-		else
-			material = 2;
-
-		if(material != material_in_use || buf == NULL)
-		{
-			// Try to get a meshbuffer associated with the material
-			buf = (scene::SMeshBuffer*)mesh_new->getMeshBuffer
-					(g_mesh_materials[material]);
-			// If not found, create one
-			if(buf == NULL)
-			{
-				// This is a "Standard MeshBuffer",
-				// it's a typedeffed CMeshBuffer<video::S3DVertex>
-				buf = new scene::SMeshBuffer();
-
-				// Set material
-				buf->Material = g_mesh_materials[material];
-				// Use VBO
-				//buf->setHardwareMappingHint(scene::EHM_STATIC);
-				// Add to mesh
-				mesh_new->addMeshBuffer(buf);
-				// Mesh grabbed it
-				buf->drop();
-			}
-			material_in_use = material;
-		}
-
-		// Sector side width in floating-point units
-		f32 sd = BS * MAP_BLOCKSIZE;
-		// Sector position in global floating-point units
-		v3f spf = v3f((f32)sp.X, 0, (f32)sp.Y) * sd;
-
-		//video::SColor c(255,255,255,255);
-		u8 cc = 180;
-		video::SColor c(255,cc,cc,cc);
-		
-		video::S3DVertex vertices[4] =
-		{
-			video::S3DVertex(spf.X,   (f32)BS*cn[0],spf.Z,   0,0,0, c, 0,1),
-			video::S3DVertex(spf.X+sd,(f32)BS*cn[1],spf.Z,   0,0,0, c, 1,1),
-			video::S3DVertex(spf.X+sd,(f32)BS*cn[2],spf.Z+sd,0,0,0, c, 1,0),
-			video::S3DVertex(spf.X,   (f32)BS*cn[3],spf.Z+sd,0,0,0, c, 0,0),
-		};
-		u16 indices[] = {0,1,2,2,3,0};
-		
-		buf->append(vertices, 4, indices, 6);
-	}
-	
-	// Set VBO on
-	//mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
-
-	/*
-		Replace the mesh
-	*/
-
-	mesh_mutex.Lock();
-
-	scene::SMesh *mesh_old = mesh;
-
-	//DEBUG
-	/*mesh = NULL;
-	mesh_new->drop();*/
-	mesh = mesh_new;
-	
-	mesh_mutex.Unlock();
-
-	if(mesh_old != NULL)
-	{
-		/*dstream<<"mesh_old refcount="<<mesh_old->getReferenceCount()
-				<<std::endl;
-		scene::IMeshBuffer *buf = mesh_new->getMeshBuffer
-				(g_materials[CONTENT_GRASS]);
-		if(buf != NULL)
-			dstream<<"grass buf refcount="<<buf->getReferenceCount()
-					<<std::endl;*/
-
-		mesh_old->drop();
-	}
-	else
-	{
-		dstream<<"WARNING: There was no old master heightmap mesh"<<std::endl;
-	}
-#endif
+	//TODO: Remove this
 }
 
 void ClientMap::PrintInfo(std::ostream &out)
diff --git a/src/map.h b/src/map.h
index 6944107df..d36e2ddad 100644
--- a/src/map.h
+++ b/src/map.h
@@ -522,7 +522,6 @@ class ClientMap : public Map, public scene::ISceneNode
 public:
 	ClientMap(
 			Client *client,
-			video::SMaterial *materials,
 			scene::ISceneNode* parent,
 			scene::ISceneManager* mgr,
 			s32 id
@@ -562,7 +561,7 @@ class ClientMap : public Map, public scene::ISceneNode
 	{
 		video::IVideoDriver* driver = SceneManager->getVideoDriver();
 		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
-		renderMap(driver, m_materials, SceneManager->getSceneNodeRenderPass());
+		renderMap(driver, SceneManager->getSceneNodeRenderPass());
 	}
 	
 	virtual const core::aabbox3d<f32>& getBoundingBox() const
@@ -570,8 +569,7 @@ class ClientMap : public Map, public scene::ISceneNode
 		return m_box;
 	}
 
-	void renderMap(video::IVideoDriver* driver,
-		video::SMaterial *materials, s32 pass);
+	void renderMap(video::IVideoDriver* driver, s32 pass);
 
 	// Update master heightmap mesh
 	void updateMesh();
@@ -582,8 +580,6 @@ class ClientMap : public Map, public scene::ISceneNode
 private:
 	Client *m_client;
 	
-	video::SMaterial *m_materials;
-
 	core::aabbox3d<f32> m_box;
 	
 	// This is the master heightmap mesh
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 4ba597f6a..40af0e397 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -138,6 +138,8 @@ FastFace * MapBlock::makeFastFace(u16 tile, u8 light, v3f p,
 			core::vector2d<f32>(0,0));
 
 	f->tile = tile;
+	//DEBUG
+	//f->tile = TILE_GRASS;
 
 	return f;
 }
@@ -184,15 +186,30 @@ u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
 }
 
 /*
-	Gets node material from any place relative to block.
+	Gets node tile from any place relative to block.
 	Returns CONTENT_IGNORE if doesn't exist or should not be drawn.
 */
-u8 MapBlock::getNodeTile(v3s16 p)
+u16 MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
 {
 	try{
 		MapNode n = getNodeParent(p);
 		
-		return content_tile(n.d);
+		//return content_tile(n.d);
+		return n.getTile(face_dir);
+	}
+	catch(InvalidPositionException &e)
+	{
+		//return CONTENT_IGNORE;
+		return TILE_NONE;
+	}
+}
+
+u8 MapBlock::getNodeContent(v3s16 p)
+{
+	try{
+		MapNode n = getNodeParent(p);
+		
+		return n.d;
 	}
 	catch(InvalidPositionException &e)
 	{
@@ -223,15 +240,14 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
 
 	v3s16 p = startpos;
 	/*
-		The light in the air lights the surface is taken from
-		the node that is air.
+		Get face light at starting position
 	*/
 	u8 light = getFaceLight(p, face_dir);
 	
 	u16 continuous_tiles_count = 0;
 	
-	u8 tile0 = getNodeTile(p);
-	u8 tile1 = getNodeTile(p + face_dir);
+	u8 tile0 = getNodeTile(p, face_dir);
+	u8 tile1 = getNodeTile(p + face_dir, -face_dir);
 		
 	for(u16 j=0; j<length; j++)
 	{
@@ -244,8 +260,8 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
 
 		if(j != length - 1){
 			p_next = p + translate_dir;
-			tile0_next = getNodeTile(p_next);
-			tile1_next = getNodeTile(p_next + face_dir);
+			tile0_next = getNodeTile(p_next, face_dir);
+			tile1_next = getNodeTile(p_next + face_dir, -face_dir);
 			light_next = getFaceLight(p_next, face_dir);
 
 			if(tile0_next == tile0
@@ -263,7 +279,11 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
 			/*
 				Create a face if there should be one
 			*/
-			u8 mf = face_contents(tile0, tile1);
+			//u8 mf = face_contents(tile0, tile1);
+			// This is hackish
+			u8 content0 = getNodeContent(p);
+			u8 content1 = getNodeContent(p + face_dir);
+			u8 mf = face_contents(content0, content1);
 			
 			if(mf != 0)
 			{
@@ -479,7 +499,9 @@ void MapBlock::updateMesh()
 
 			/*collector.append(g_materials[f->material], f->vertices, 4,
 					indices, 6);*/
-			collector.append(g_materials[f->tile], f->vertices, 4,
+			/*collector.append(g_materials[f->tile], f->vertices, 4,
+					indices, 6);*/
+			collector.append(g_tile_materials[f->tile], f->vertices, 4,
 					indices, 6);
 		}
 
diff --git a/src/mapblock.h b/src/mapblock.h
index f725aa1f5..b9c5ff222 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -288,7 +288,8 @@ class MapBlock : public NodeContainer
 	
 	u8 getFaceLight(v3s16 p, v3s16 face_dir);
 	
-	u8 getNodeTile(v3s16 p);
+	u16 getNodeTile(v3s16 p, v3s16 face_dir);
+	u8 getNodeContent(v3s16 p);
 
 	/*
 		startpos:
diff --git a/src/mapnode.h b/src/mapnode.h
index 77fd677da..b2c499f08 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "utility.h"
 #include "exceptions.h"
 #include "serialization.h"
+#include "tile.h"
 
 // Size of node in rendering units
 #define BS 10
@@ -64,30 +65,23 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 enum Content
 {
-	CONTENT_STONE=0,
-
-	CONTENT_GRASS=1,
-
-	CONTENT_WATER=2,
-
-	CONTENT_LIGHT=3,
-
-	CONTENT_TREE=4,
-	
-	CONTENT_LEAVES=5,
-
-	CONTENT_GRASS_FOOTSTEPS=6,
-	
-	CONTENT_MESE=7,
-
-	CONTENT_MUD=8,
-
-	CONTENT_OCEAN=9,
+	CONTENT_STONE,
+	CONTENT_GRASS,
+	CONTENT_WATER,
+	CONTENT_LIGHT,
+	CONTENT_TREE,
+	CONTENT_LEAVES,
+	CONTENT_GRASS_FOOTSTEPS,
+	CONTENT_MESE,
+	CONTENT_MUD,
+	CONTENT_OCEAN,
 	
 	// This is set to the number of the actual values in this enum
 	USEFUL_CONTENT_COUNT
 };
 
+extern u16 g_content_tiles[USEFUL_CONTENT_COUNT][6];
+
 /*
 	If true, the material allows light propagation and brightness is stored
 	in param.
@@ -149,18 +143,6 @@ inline bool content_buildable_to(u8 m)
 	return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_OCEAN);
 }
 
-/*
-	TODO: Make a mapper class for mapping every side of a content
-	      to some tile.
-	This dumbily maps all sides of content to the tile of the same id.
-*/
-inline u8 content_tile(u8 c)
-{
-	if(c == CONTENT_IGNORE || c == CONTENT_LIGHT)
-		return CONTENT_AIR;
-	return c;
-}
-
 /*
 	Returns true for contents that form the base ground that
 	follows the main heightmap
@@ -260,6 +242,34 @@ 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];
+}
+
 struct MapNode
 {
 	// Content
@@ -351,6 +361,11 @@ struct MapNode
 		param = a_light;
 	}
 
+	u16 getTile(v3s16 dir)
+	{
+		return content_tile(d, dir);
+	}
+
 	/*
 		These serialization functions are used when informing client
 		of a single node add
diff --git a/src/test.cpp b/src/test.cpp
index 91d7c1e40..ce7540e8d 100644
--- a/src/test.cpp
+++ b/src/test.cpp
@@ -321,7 +321,7 @@ struct TestVoxelManipulator
 
 		v.print(dstream, VOXELPRINT_WATERPRESSURE);
 		
-		s16 highest_y = -32768;
+		//s16 highest_y = -32768;
 		/*
 			NOTE: These are commented out because this behaviour is changed
 			      all the time
@@ -484,8 +484,9 @@ struct TestMapBlock
 		n.d = 4;
 		b.setNode(p, n);
 		assert(b.getNode(p).d == 4);
-		assert(b.getNodeTile(p) == 4);
-		assert(b.getNodeTile(v3s16(-1,-1,0)) == 5);
+		//TODO: Update to new system
+		/*assert(b.getNodeTile(p) == 4);
+		assert(b.getNodeTile(v3s16(-1,-1,0)) == 5);*/
 		
 		/*
 			propagateSunlight()
diff --git a/src/utility.h b/src/utility.h
index 4c9a2d73a..afcb4e414 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -24,10 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef UTILITY_HEADER
 #define UTILITY_HEADER
 
-#include "common_irrlicht.h"
-#include "debug.h"
-#include "strfnd.h"
-#include "exceptions.h"
 #include <iostream>
 #include <fstream>
 #include <string>
@@ -35,6 +31,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <jmutex.h>
 #include <jmutexautolock.h>
 
+#include "common_irrlicht.h"
+#include "debug.h"
+#include "strfnd.h"
+#include "exceptions.h"
+
 extern const v3s16 g_26dirs[26];
 
 inline void writeU32(u8 *data, u32 i)
-- 
GitLab