diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9c0751fe6..7231ec6a8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@
 #         Stratagus - A free fantasy real time strategy game engine
 #
 #    CMakeLists.txt
-#    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>
+#    Copyright (C) 2011-2013  Pali Rohár <pali.rohar@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
@@ -189,8 +189,8 @@ set(map_SRCS
 	src/map/map_draw.cpp
 	src/map/map_fog.cpp
 	src/map/map_radar.cpp
-	src/map/map_save.cpp
 	src/map/map_wall.cpp
+	src/map/mapfield.cpp
 	src/map/minimap.cpp
 	src/map/script_map.cpp
 	src/map/script_tileset.cpp
diff --git a/src/editor/editloop.cpp b/src/editor/editloop.cpp
index ed3131c26..dc3bf9465 100644
--- a/src/editor/editloop.cpp
+++ b/src/editor/editloop.cpp
@@ -184,16 +184,11 @@ static void EditTile(const Vec2i &pos, int tile)
 {
 	Assert(Map.Info.IsPointOnMap(pos));
 
-	int tileIndex = Map.Tileset->findTileIndexByTile(tile);
-
-	ChangeTile(pos, Map.Tileset->getTileNumber(tileIndex, TileToolRandom, TileToolDecoration));
-
-	// Change the flags
+	const CTileset &tileset = *Map.Tileset;
+	const int baseTileIndex = tileset.findTileIndexByTile(tile);
+	const int tileIndex = tileset.getTileNumber(baseTileIndex, TileToolRandom, TileToolDecoration);
 	CMapField &mf = *Map.Field(pos);
-	mf.Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed |
-				  MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable |
-				  MapFieldWall | MapFieldRocks | MapFieldForest);
-	mf.Flags |= Map.Tileset->FlagsTable[tileIndex];
+	mf.setTileIndex(tileset, tileIndex, 0);
 
 	UI.Minimap.UpdateSeenXY(pos);
 	UI.Minimap.UpdateXY(pos);
diff --git a/src/editor/edmap.cpp b/src/editor/edmap.cpp
index 0e98a5674..28d9827be 100644
--- a/src/editor/edmap.cpp
+++ b/src/editor/edmap.cpp
@@ -98,15 +98,9 @@ static void EditorChangeTile(const Vec2i &pos, int tileIndex, int d)
 {
 	Assert(Map.Info.IsPointOnMap(pos));
 
-	ChangeTile(pos, Map.Tileset->Table[tileIndex]);
-
 	// Change the flags
 	CMapField &mf = *Map.Field(pos);
-	mf.Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed
-				  | MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable
-				  | MapFieldWall | MapFieldRocks | MapFieldForest);
-
-	mf.Flags |= Map.Tileset->FlagsTable[tileIndex];
+	mf.setTileIndex(*Map.Tileset, tileIndex, 0);
 
 	UI.Minimap.UpdateSeenXY(pos);
 	UI.Minimap.UpdateXY(pos);
diff --git a/src/include/editor.h b/src/include/editor.h
index 97e5976bc..bf385e772 100644
--- a/src/include/editor.h
+++ b/src/include/editor.h
@@ -127,8 +127,6 @@ extern int EditorSaveMap(const std::string &file);
 /// Register ccl features
 extern void EditorCclRegister();
 
-/// Change the view of a tile
-extern void ChangeTile(const Vec2i &pos, int tile);
 /// Update surroundings for tile changes
 extern void EditorTileChanged(const Vec2i &pos);
 
diff --git a/src/include/tile.h b/src/include/tile.h
index c27a490d0..849770d81 100644
--- a/src/include/tile.h
+++ b/src/include/tile.h
@@ -140,6 +140,8 @@
 
 class CFile;
 class CPlayer;
+class CTileset;
+struct lua_State;
 
 /*----------------------------------------------------------------------------
 --  Map - field
@@ -200,18 +202,16 @@ public:
 	unsigned char RadarJammer[PlayerMax]; /// Jamming capabilities.
 };
 
-
 /// Describes a field of the map
 class CMapField
 {
 public:
-	CMapField() : Tile(0), Flags(0), Cost(0), Value(0), UnitCache()
-#ifdef DEBUG
-		, TilesetTile(0)
-#endif
-	{}
+	CMapField();
 
 	void Save(CFile &file) const;
+	void parse(lua_State *l);
+
+	void setTileIndex(const CTileset &tileset, unsigned int tileIndex, int value);
 
 	/// Check if a field flags.
 	bool CheckMask(int mask) const {
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 703814d77..afad5ffdc 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -38,11 +38,13 @@
 
 #include "map.h"
 
+#include "iolib.h"
 #include "player.h"
 #include "tileset.h"
 #include "unit.h"
 #include "unit_manager.h"
 #include "ui.h"
+#include "version.h"
 #include "video.h"
 
 /*----------------------------------------------------------------------------
@@ -178,66 +180,6 @@ PixelPos CMap::TilePosToMapPixelPos_Center(const Vec2i &tilePos) const
 	return TilePosToMapPixelPos_TopLeft(tilePos) + PixelTileSize / 2;
 }
 
-bool CMapField::IsTerrainResourceOnMap(int resource) const
-{
-	// TODO: Hard coded stuff.
-	if (resource == WoodCost) {
-		return this->ForestOnMap();
-	}
-	return false;
-}
-
-bool CMapField::IsTerrainResourceOnMap() const
-{
-	for (int i = 0; i != MaxCosts; ++i) {
-		if (IsTerrainResourceOnMap(i)) {
-			return true;
-		}
-	}
-	return false;
-}
-
-unsigned char CMapFieldPlayerInfo::TeamVisibilityState(const CPlayer &player) const
-{
-	if (IsVisible(player)) {
-		return 2;
-	}
-
-	unsigned char maxVision = 0;
-	if (IsExplored(player)) {
-		maxVision = 1;
-	}
-
-	for (int i = 0; i != PlayerMax ; ++i) {
-		if (player.IsBothSharedVision(Players[i])) {
-			maxVision = std::max<unsigned char>(maxVision, Visible[i]);
-			if (maxVision >= 2) {
-				return 2;
-			}
-		}
-	}
-	if (maxVision == 1 && Map.NoFogOfWar) {
-		return 2;
-	}
-	return maxVision;
-}
-
-bool CMapFieldPlayerInfo::IsExplored(const CPlayer &player) const
-{
-	return Visible[player.Index] != 0;
-}
-
-bool CMapFieldPlayerInfo::IsVisible(const CPlayer &player) const
-{
-	const bool fogOfWar = !Map.NoFogOfWar;
-	return Visible[player.Index] >= 2 || (!fogOfWar && IsExplored(player));
-}
-
-bool CMapFieldPlayerInfo::IsTeamVisible(const CPlayer &player) const
-{
-	return TeamVisibilityState(player) == 2;
-}
-
 /**
 **  Wall on map tile.
 **
@@ -420,6 +362,41 @@ void CMap::Clean()
 }
 
 
+
+/**
+** Save the complete map.
+**
+** @param file Output file.
+*/
+void CMap::Save(CFile &file) const
+{
+	file.printf("\n--- -----------------------------------------\n");
+	file.printf("--- MODULE: map\n");
+	file.printf("LoadTileModels(\"%s\")\n\n", this->TileModelsFileName.c_str());
+	file.printf("StratagusMap(\n");
+	file.printf("  \"version\", \"%s\",\n", VERSION);
+	file.printf("  \"description\", \"%s\",\n", this->Info.Description.c_str());
+	file.printf("  \"the-map\", {\n");
+	file.printf("  \"size\", {%d, %d},\n", this->Info.MapWidth, this->Info.MapHeight);
+	file.printf("  \"%s\",\n", this->NoFogOfWar ? "no-fog-of-war" : "fog-of-war");
+	file.printf("  \"filename\", \"%s\",\n", this->Info.Filename.c_str());
+	file.printf("  \"map-fields\", {\n");
+	for (int h = 0; h < this->Info.MapHeight; ++h) {
+		file.printf("  -- %d\n", h);
+		for (int w = 0; w < this->Info.MapWidth; ++w) {
+			const CMapField &mf = *this->Field(w, h);
+
+			mf.Save(file);
+			if (w & 1) {
+				file.printf(",\n");
+			} else {
+				file.printf(", ");
+			}
+		}
+	}
+	file.printf("}})\n");
+}
+
 /*----------------------------------------------------------------------------
 -- Map Tile Update Functions
 ----------------------------------------------------------------------------*/
diff --git a/src/map/map_save.cpp b/src/map/map_save.cpp
deleted file mode 100644
index f9ca29c32..000000000
--- a/src/map/map_save.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-//       _________ __                 __
-//      /   _____//  |_____________ _/  |______     ____  __ __  ______
-//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
-//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
-//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
-//             \/                  \/          \//_____/            \/
-//  ______________________                           ______________________
-//                        T H E   W A R   B E G I N S
-//         Stratagus - A free fantasy real time strategy game engine
-//
-/**@name map_save.cpp - Saving the map. */
-//
-//      (c) Copyright 2001-2005 by Lutz Sammer and Jimmy Salmon
-//
-//      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; only version 2 of the License.
-//
-//      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., 59 Temple Place - Suite 330, Boston, MA
-//      02111-1307, USA.
-//
-
-//@{
-
-/*----------------------------------------------------------------------------
--- Includes
-----------------------------------------------------------------------------*/
-
-#include "stratagus.h"
-#include "map.h"
-
-#include "iolib.h"
-#include "version.h"
-
-/*----------------------------------------------------------------------------
--- Variables
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
--- Functions
-----------------------------------------------------------------------------*/
-
-void CMapField::Save(CFile &file) const
-{
-	file.printf("  {%3d, %3d, %2d, %2d,", Tile, playerInfo.SeenTile, Value, Cost);
-	for (int i = 0; i != PlayerMax; ++i) {
-		if (playerInfo.Visible[i] == 1) {
-			file.printf(" \"explored\", %d,", i);
-		}
-	}
-	if (Flags & MapFieldHuman) {
-		file.printf(" \"human\",");
-	}
-	if (Flags & MapFieldLandAllowed) {
-		file.printf(" \"land\",");
-	}
-	if (Flags & MapFieldCoastAllowed) {
-		file.printf(" \"coast\",");
-	}
-	if (Flags & MapFieldWaterAllowed) {
-		file.printf(" \"water\",");
-	}
-	if (Flags & MapFieldNoBuilding) {
-		file.printf(" \"mud\",");
-	}
-	if (Flags & MapFieldUnpassable) {
-		file.printf(" \"block\",");
-	}
-	if (Flags & MapFieldWall) {
-		file.printf(" \"wall\",");
-	}
-	if (Flags & MapFieldRocks) {
-		file.printf(" \"rock\",");
-	}
-	if (Flags & MapFieldForest) {
-		file.printf(" \"wood\",");
-	}
-#if 1
-	// Not Required for save
-	// These are required for now, UnitType::FieldFlags is 0 until
-	// UpdateStats is called which is after the game is loaded
-	if (Flags & MapFieldLandUnit) {
-		file.printf(" \"ground\",");
-	}
-	if (Flags & MapFieldAirUnit) {
-		file.printf(" \"air\",");
-	}
-	if (Flags & MapFieldSeaUnit) {
-		file.printf(" \"sea\",");
-	}
-	if (Flags & MapFieldBuilding) {
-		file.printf(" \"building\",");
-	}
-#endif
-	file.printf("}");
-}
-
-/**
-** Save the complete map.
-**
-** @param file Output file.
-*/
-void CMap::Save(CFile &file) const
-{
-	file.printf("\n--- -----------------------------------------\n");
-	file.printf("--- MODULE: map\n");
-
-	file.printf("LoadTileModels(\"%s\")\n\n", this->TileModelsFileName.c_str());
-
-	file.printf("StratagusMap(\n");
-
-	file.printf("  \"version\", \"%s\",\n", VERSION);
-
-	file.printf("  \"description\", \"%s\",\n", this->Info.Description.c_str());
-
-	file.printf("  \"the-map\", {\n");
-
-	file.printf("  \"size\", {%d, %d},\n", this->Info.MapWidth, this->Info.MapHeight);
-	file.printf("  \"%s\",\n", this->NoFogOfWar ? "no-fog-of-war" : "fog-of-war");
-	file.printf("  \"filename\", \"%s\",\n", this->Info.Filename.c_str());
-
-	file.printf("  \"map-fields\", {\n");
-	for (int h = 0; h < this->Info.MapHeight; ++h) {
-		file.printf("  -- %d\n", h);
-		for (int w = 0; w < this->Info.MapWidth; ++w) {
-			const CMapField &mf = *this->Field(w, h);
-
-			mf.Save(file);
-			if (w & 1) {
-				file.printf(",\n");
-			} else {
-				file.printf(", ");
-			}
-		}
-	}
-	file.printf("}})\n");
-}
-
-//@}
diff --git a/src/map/mapfield.cpp b/src/map/mapfield.cpp
new file mode 100644
index 000000000..41ba365a2
--- /dev/null
+++ b/src/map/mapfield.cpp
@@ -0,0 +1,261 @@
+//       _________ __                 __
+//      /   _____//  |_____________ _/  |______     ____  __ __  ______
+//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
+//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
+//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
+//             \/                  \/          \//_____/            \/
+//  ______________________                           ______________________
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
+//
+/**@name mapfield.cpp - The map field. */
+//
+//      (c) Copyright 2013 by Joris Dauphin
+//
+//      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; only version 2 of the License.
+//
+//      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., 59 Temple Place - Suite 330, Boston, MA
+//      02111-1307, USA.
+//
+
+//@{
+
+/*----------------------------------------------------------------------------
+--  Includes
+----------------------------------------------------------------------------*/
+
+#include "stratagus.h"
+
+#include "tile.h"
+
+#include "iolib.h"
+#include "map.h"
+#include "player.h"
+#include "script.h"
+#include "tileset.h"
+#include "unit.h"
+#include "unit_manager.h"
+
+CMapField::CMapField() :
+	Tile(0),
+	Flags(0),
+	Cost(0),
+	Value(0),
+	UnitCache()
+#ifdef DEBUG
+	, TilesetTile(0)
+#endif
+{}
+
+bool CMapField::IsTerrainResourceOnMap(int resource) const
+{
+	// TODO: Hard coded stuff.
+	if (resource == WoodCost) {
+		return this->ForestOnMap();
+	}
+	return false;
+}
+
+bool CMapField::IsTerrainResourceOnMap() const
+{
+	for (int i = 0; i != MaxCosts; ++i) {
+		if (IsTerrainResourceOnMap(i)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+void CMapField::setTileIndex(const CTileset &tileset, unsigned int tileIndex, int value)
+{
+	this->Tile = tileset.Table[tileIndex];
+	this->playerInfo.SeenTile = Tile;
+
+	this->Value = value;
+#if 0
+	this->Flags = tileset.FlagsTable[tileIndex];
+#else
+	this->Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed |
+					 MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable |
+					 MapFieldWall | MapFieldRocks | MapFieldForest);
+	this->Flags |= tileset.FlagsTable[tileIndex];
+#endif
+	this->Cost = 1 << (tileset.FlagsTable[tileIndex] & MapFieldSpeedMask);
+#ifdef DEBUG
+	this->TilesetTile = tileIndex;
+#endif
+}
+
+void CMapField::Save(CFile &file) const
+{
+	file.printf("  {%3d, %3d, %2d, %2d", Tile, playerInfo.SeenTile, Value, Cost);
+	for (int i = 0; i != PlayerMax; ++i) {
+		if (playerInfo.Visible[i] == 1) {
+			file.printf(", \"explored\", %d", i);
+		}
+	}
+	if (Flags & MapFieldHuman) {
+		file.printf(", \"human\"");
+	}
+	if (Flags & MapFieldLandAllowed) {
+		file.printf(", \"land\"");
+	}
+	if (Flags & MapFieldCoastAllowed) {
+		file.printf(", \"coast\"");
+	}
+	if (Flags & MapFieldWaterAllowed) {
+		file.printf(", \"water\"");
+	}
+	if (Flags & MapFieldNoBuilding) {
+		file.printf(", \"mud\"");
+	}
+	if (Flags & MapFieldUnpassable) {
+		file.printf(", \"block\"");
+	}
+	if (Flags & MapFieldWall) {
+		file.printf(", \"wall\"");
+	}
+	if (Flags & MapFieldRocks) {
+		file.printf(", \"rock\"");
+	}
+	if (Flags & MapFieldForest) {
+		file.printf(", \"wood\"");
+	}
+#if 1
+	// Not Required for save
+	// These are required for now, UnitType::FieldFlags is 0 until
+	// UpdateStats is called which is after the game is loaded
+	if (Flags & MapFieldLandUnit) {
+		file.printf(", \"ground\"");
+	}
+	if (Flags & MapFieldAirUnit) {
+		file.printf(", \"air\"");
+	}
+	if (Flags & MapFieldSeaUnit) {
+		file.printf(", \"sea\"");
+	}
+	if (Flags & MapFieldBuilding) {
+		file.printf(", \"building\"");
+	}
+#endif
+	file.printf("}");
+}
+
+
+void CMapField::parse(lua_State *l)
+{
+	if (!lua_istable(l, -1)) {
+		LuaError(l, "incorrect argument");
+	}
+	const int len = lua_rawlen(l, -1);
+	if (len < 4) {
+		LuaError(l, "incorrect argument");
+	}
+
+	lua_rawgeti(l, -1, 1);
+	this->Tile = LuaToNumber(l, -1);
+	lua_pop(l, 1);
+	lua_rawgeti(l, -1, 2);
+	this->playerInfo.SeenTile = LuaToNumber(l, -1);
+	lua_pop(l, 1);
+	lua_rawgeti(l, -1, 3);
+	this->Value = LuaToNumber(l, -1);
+	lua_pop(l, 1);
+	lua_rawgeti(l, -1, 4);
+	this->Cost = LuaToNumber(l, -1);
+	lua_pop(l, 1);
+
+	for (int j = 4; j < len; ++j) {
+		lua_rawgeti(l, -1, j + 1);
+		const char *value = LuaToString(l, -1);
+		lua_pop(l, 1);
+		if (!strcmp(value, "explored")) {
+			++j;
+			lua_rawgeti(l, -1, j + 1);
+			this->playerInfo.Visible[LuaToNumber(l, -1)] = 1;
+			lua_pop(l, 1);
+		} else if (!strcmp(value, "human")) {
+			this->Flags |= MapFieldHuman;
+		} else if (!strcmp(value, "land")) {
+			this->Flags |= MapFieldLandAllowed;
+		} else if (!strcmp(value, "coast")) {
+			this->Flags |= MapFieldCoastAllowed;
+		} else if (!strcmp(value, "water")) {
+			this->Flags |= MapFieldWaterAllowed;
+		} else if (!strcmp(value, "mud")) {
+			this->Flags |= MapFieldNoBuilding;
+		} else if (!strcmp(value, "block")) {
+			this->Flags |= MapFieldUnpassable;
+		} else if (!strcmp(value, "wall")) {
+			this->Flags |= MapFieldWall;
+		} else if (!strcmp(value, "rock")) {
+			this->Flags |= MapFieldRocks;
+		} else if (!strcmp(value, "wood")) {
+			this->Flags |= MapFieldForest;
+		} else if (!strcmp(value, "ground")) {
+			this->Flags |= MapFieldLandUnit;
+		} else if (!strcmp(value, "air")) {
+			this->Flags |= MapFieldAirUnit;
+		} else if (!strcmp(value, "sea")) {
+			this->Flags |= MapFieldSeaUnit;
+		} else if (!strcmp(value, "building")) {
+			this->Flags |= MapFieldBuilding;
+		} else {
+			LuaError(l, "Unsupported tag: %s" _C_ value);
+		}
+	}
+}
+
+//
+//  CMapFieldPlayerInfo
+//
+
+unsigned char CMapFieldPlayerInfo::TeamVisibilityState(const CPlayer &player) const
+{
+	if (IsVisible(player)) {
+		return 2;
+	}
+	unsigned char maxVision = 0;
+	if (IsExplored(player)) {
+		maxVision = 1;
+	}
+	for (int i = 0; i != PlayerMax ; ++i) {
+		if (player.IsBothSharedVision(Players[i])) {
+			maxVision = std::max<unsigned char>(maxVision, Visible[i]);
+			if (maxVision >= 2) {
+				return 2;
+			}
+		}
+	}
+	if (maxVision == 1 && Map.NoFogOfWar) {
+		return 2;
+	}
+	return maxVision;
+}
+
+bool CMapFieldPlayerInfo::IsExplored(const CPlayer &player) const
+{
+	return Visible[player.Index] != 0;
+}
+
+bool CMapFieldPlayerInfo::IsVisible(const CPlayer &player) const
+{
+	const bool fogOfWar = !Map.NoFogOfWar;
+	return Visible[player.Index] >= 2 || (!fogOfWar && IsExplored(player));
+}
+
+bool CMapFieldPlayerInfo::IsTeamVisible(const CPlayer &player) const
+{
+	return TeamVisibilityState(player) == 2;
+}
+
+//@}
diff --git a/src/map/script_map.cpp b/src/map/script_map.cpp
index 7ae18dec7..36390a150 100644
--- a/src/map/script_map.cpp
+++ b/src/map/script_map.cpp
@@ -107,82 +107,17 @@ static int CclStratagusMap(lua_State *l)
 					if (!lua_istable(l, -1)) {
 						LuaError(l, "incorrect argument");
 					}
-
 					const int subsubargs = lua_rawlen(l, -1);
 					if (subsubargs != Map.Info.MapWidth * Map.Info.MapHeight) {
 						fprintf(stderr, "Wrong tile table length: %d\n", subsubargs);
 					}
-					int i = 0;
-					for (int subk = 0; subk < subsubargs; ++subk) {
-						lua_rawgeti(l, -1, subk + 1);
+					for (int i = 0; i < subsubargs; ++i) {
+						lua_rawgeti(l, -1, i + 1);
 						if (!lua_istable(l, -1)) {
 							LuaError(l, "incorrect argument");
 						}
-						int args2 = lua_rawlen(l, -1);
-						int j2 = 0;
-
-						lua_rawgeti(l, -1, j2 + 1);
-						Map.Fields[i].Tile = LuaToNumber(l, -1);
+						Map.Fields[i].parse(l);
 						lua_pop(l, 1);
-						++j2;
-						lua_rawgeti(l, -1, j2 + 1);
-						Map.Fields[i].playerInfo.SeenTile = LuaToNumber(l, -1);
-						lua_pop(l, 1);
-						++j2;
-						lua_rawgeti(l, -1, j2 + 1);
-						Map.Fields[i].Value = LuaToNumber(l, -1);
-						lua_pop(l, 1);
-						++j2;
-						lua_rawgeti(l, -1, j2 + 1);
-						Map.Fields[i].Cost = LuaToNumber(l, -1);
-						lua_pop(l, 1);
-						++j2;
-						for (; j2 < args2; ++j2) {
-							lua_rawgeti(l, -1, j2 + 1);
-							value = LuaToString(l, -1);
-							lua_pop(l, 1);
-							if (!strcmp(value, "explored")) {
-								++j2;
-								lua_rawgeti(l, -1, j2 + 1);
-								Map.Fields[i].playerInfo.Visible[LuaToNumber(l, -1)] = 1;
-								lua_pop(l, 1);
-							} else if (!strcmp(value, "human")) {
-								Map.Fields[i].Flags |= MapFieldHuman;
-
-							} else if (!strcmp(value, "land")) {
-								Map.Fields[i].Flags |= MapFieldLandAllowed;
-							} else if (!strcmp(value, "coast")) {
-								Map.Fields[i].Flags |= MapFieldCoastAllowed;
-							} else if (!strcmp(value, "water")) {
-								Map.Fields[i].Flags |= MapFieldWaterAllowed;
-
-							} else if (!strcmp(value, "mud")) {
-								Map.Fields[i].Flags |= MapFieldNoBuilding;
-							} else if (!strcmp(value, "block")) {
-								Map.Fields[i].Flags |= MapFieldUnpassable;
-
-							} else if (!strcmp(value, "wall")) {
-								Map.Fields[i].Flags |= MapFieldWall;
-							} else if (!strcmp(value, "rock")) {
-								Map.Fields[i].Flags |= MapFieldRocks;
-							} else if (!strcmp(value, "wood")) {
-								Map.Fields[i].Flags |= MapFieldForest;
-
-							} else if (!strcmp(value, "ground")) {
-								Map.Fields[i].Flags |= MapFieldLandUnit;
-							} else if (!strcmp(value, "air")) {
-								Map.Fields[i].Flags |= MapFieldAirUnit;
-							} else if (!strcmp(value, "sea")) {
-								Map.Fields[i].Flags |= MapFieldSeaUnit;
-							} else if (!strcmp(value, "building")) {
-								Map.Fields[i].Flags |= MapFieldBuilding;
-
-							} else {
-								LuaError(l, "Unsupported tag: %s" _C_ value);
-							}
-						}
-						lua_pop(l, 1);
-						++i;
 					}
 					lua_pop(l, 1);
 				} else {
@@ -400,35 +335,29 @@ static int CclSetFogOfWarGraphics(lua_State *l)
 /**
 **  Set a tile
 **
-**  @param tile   Tile number
+**  @param tileIndex   Tile number
 **  @param pos    coordinate
 **  @param value  Value of the tile
 */
-void SetTile(int tile, const Vec2i &pos, int value)
+void SetTile(int tileIndex, const Vec2i &pos, int value)
 {
 	if (!Map.Info.IsPointOnMap(pos)) {
 		fprintf(stderr, "Invalid map coordonate : (%d, %d)\n", pos.x, pos.y);
 		return;
 	}
-	if (tile < 0 || tile >= Map.Tileset->NumTiles) {
-		fprintf(stderr, "Invalid tile number: %d\n", tile);
+	if (tileIndex < 0 || tileIndex >= Map.Tileset->NumTiles) {
+		fprintf(stderr, "Invalid tile number: %d\n", tileIndex);
 		return;
 	}
 	if (value < 0 || value >= 256) {
-		fprintf(stderr, "Invalid tile number: %d\n", tile);
+		fprintf(stderr, "Invalid tile number: %d\n", tileIndex);
 		return;
 	}
 
 	if (Map.Fields) {
 		CMapField &mf = *Map.Field(pos);
 
-		mf.Tile = Map.Tileset->Table[tile];
-		mf.Value = value;
-		mf.Flags = Map.Tileset->FlagsTable[tile];
-		mf.Cost = 1 << (Map.Tileset->FlagsTable[tile] & MapFieldSpeedMask);
-#ifdef DEBUG
-		mf.TilesetTile = tile;
-#endif
+		mf.setTileIndex(*Map.Tileset, tileIndex, value);
 	}
 }
 
diff --git a/src/map/tileset.cpp b/src/map/tileset.cpp
index 1cbe5959c..b61053385 100644
--- a/src/map/tileset.cpp
+++ b/src/map/tileset.cpp
@@ -523,7 +523,7 @@ int CTileset::findTileIndexByTile(unsigned int tile) const
 **  @param random  Return random tile
 **  @param filler  Get a decorated tile.
 **
-**  @return        Tile number.
+**  @return        Tile index number.
 **
 **  @todo  FIXME: Solid tiles are here still hardcoded.
 */
@@ -548,7 +548,7 @@ unsigned int CTileset::getTileNumber(int basic, bool random, bool filler) const
 			}
 		} while (i < 16 && n--);
 		Assert(i != 16);
-		return Table[tile + i];
+		return tile + i;
 	}
 	if (filler) {
 		int i = 0;
@@ -557,10 +557,10 @@ unsigned int CTileset::getTileNumber(int basic, bool random, bool filler) const
 		for (; i < 16 && !Table[tile + i]; ++i) {
 		}
 		if (i != 16) {
-			return Table[tile + i];
+			return tile + i;
 		}
 	}
-	return Table[tile];
+	return tile;
 }
 
 /**