← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/market into lp:widelands

 

SirVer has proposed merging lp:~widelands-dev/widelands/market into lp:widelands.

Commit message:
Adds a new building type called 'Market' that will be the trading building for land-based trading.

This only adds the (massive) boilerplate and a simple test that the new building can actually be build. I'd like to get this in before adding the logic, so future merge requests are smaller.

The test is run with the regular regression test runs, but can be run standalone using:

./build/debug/src/widelands --datadir=data --datadir_for_testing=test \
   --scenario=maps/market_trading.wmf \
   --script=maps/market_trading.wmf/scripting/test_market_can_be_build.lua

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/market/+merge/330830
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/market into lp:widelands.
=== modified file 'data/tribes/barbarians.lua'
--- data/tribes/barbarians.lua	2017-07-19 20:40:32 +0000
+++ data/tribes/barbarians.lua	2017-09-15 13:27:37 +0000
@@ -176,6 +176,9 @@
       "barbarians_warehouse",
       "barbarians_port",
 
+      -- Markets
+      "barbarians_market",
+
       -- Small
       "barbarians_quarry",
       "barbarians_lumberjacks_hut",

=== added directory 'data/tribes/buildings/markets'
=== added directory 'data/tribes/buildings/markets/barbarians'
=== added directory 'data/tribes/buildings/markets/barbarians/market'
=== added file 'data/tribes/buildings/markets/barbarians/market/build_00.png'
Binary files data/tribes/buildings/markets/barbarians/market/build_00.png	1970-01-01 00:00:00 +0000 and data/tribes/buildings/markets/barbarians/market/build_00.png	2017-09-15 13:27:37 +0000 differ
=== added file 'data/tribes/buildings/markets/barbarians/market/helptexts.lua'
--- data/tribes/buildings/markets/barbarians/market/helptexts.lua	1970-01-01 00:00:00 +0000
+++ data/tribes/buildings/markets/barbarians/market/helptexts.lua	2017-09-15 13:27:37 +0000
@@ -0,0 +1,27 @@
+-- This include can be removed when all help texts have been defined.
+include "tribes/scripting/help/global_helptexts.lua"
+
+function building_helptext_lore()
+   -- TRANSLATORS#: Lore helptext for a building
+   return no_lore_text_yet()
+end
+
+function building_helptext_lore_author()
+   -- TRANSLATORS#: Lore author helptext for a building
+   return no_lore_author_text_yet()
+end
+
+function building_helptext_purpose()
+   -- TRANSLATORS: Purpose helptext for a building
+   return pgettext("barbarians_building", "TODO: Document market once its use stabilizes.")
+end
+
+function building_helptext_note()
+   -- TRANSLATORS#: Note helptext for a building
+   return ""
+end
+
+function building_helptext_performance()
+   -- TRANSLATORS#: Performance helptext for a building
+   return ""
+end

=== added file 'data/tribes/buildings/markets/barbarians/market/idle_00.png'
Binary files data/tribes/buildings/markets/barbarians/market/idle_00.png	1970-01-01 00:00:00 +0000 and data/tribes/buildings/markets/barbarians/market/idle_00.png	2017-09-15 13:27:37 +0000 differ
=== added file 'data/tribes/buildings/markets/barbarians/market/idle_00_pc.png'
Binary files data/tribes/buildings/markets/barbarians/market/idle_00_pc.png	1970-01-01 00:00:00 +0000 and data/tribes/buildings/markets/barbarians/market/idle_00_pc.png	2017-09-15 13:27:37 +0000 differ
=== added file 'data/tribes/buildings/markets/barbarians/market/init.lua'
--- data/tribes/buildings/markets/barbarians/market/init.lua	1970-01-01 00:00:00 +0000
+++ data/tribes/buildings/markets/barbarians/market/init.lua	2017-09-15 13:27:37 +0000
@@ -0,0 +1,49 @@
+dirname = path.dirname(__file__)
+
+tribes:new_market_type {
+   msgctxt = "barbarians_building",
+   name = "barbarians_market",
+   -- TRANSLATORS: This is a building name used in lists of buildings
+   descname = pgettext("barbarians_building", "Market"),
+   helptext_script = dirname .. "helptexts.lua",
+   icon = dirname .. "menu.png",
+   size = "medium",
+
+   buildcost = {
+      log = 8,
+      blackwood = 6,
+      granite = 4,
+      grout = 3,
+      iron = 1,
+      thatch_reed = 4,
+      gold = 2,
+   },
+   return_on_dismantle = {
+      log = 4,
+      blackwood = 3,
+      granite = 3,
+      grout = 1,
+      iron = 1,
+      thatch_reed = 2,
+      gold = 1,
+   },
+
+   animations = {
+      idle = {
+         pictures = path.list_files(dirname .. "idle_??.png"),
+         hotspot = { 67, 80 },
+      },
+      build = {
+         pictures = path.list_files(dirname .. "build_??.png"),
+         hotspot = { 67, 80 },
+      }
+   },
+
+   aihints = {
+      prohibited_till = 1000
+   },
+
+   working_positions = {
+      barbarians_ox = 10,
+   },
+}

=== added file 'data/tribes/buildings/markets/barbarians/market/menu.png'
Binary files data/tribes/buildings/markets/barbarians/market/menu.png	1970-01-01 00:00:00 +0000 and data/tribes/buildings/markets/barbarians/market/menu.png	2017-09-15 13:27:37 +0000 differ
=== modified file 'data/tribes/init.lua'
--- data/tribes/init.lua	2017-02-12 09:10:57 +0000
+++ data/tribes/init.lua	2017-09-15 13:27:37 +0000
@@ -290,6 +290,13 @@
    end)
 
    -- ===================================
+   --    Markets
+   -- ===================================
+
+   print_loading_message("┃    Markets", function()
+      include "tribes/buildings/markets/barbarians/market/init.lua"
+   end)
+   -- ===================================
    --    Productionsites
    -- ===================================
 

=== modified file 'data/tribes/scripting/starting_conditions/barbarians/fortified_village.lua'
--- data/tribes/scripting/starting_conditions/barbarians/fortified_village.lua	2016-12-03 16:37:13 +0000
+++ data/tribes/scripting/starting_conditions/barbarians/fortified_village.lua	2017-09-15 13:27:37 +0000
@@ -19,6 +19,7 @@
          sf = shared_in_start
       else
          plr:allow_workers("all")
+         plr:forbid_buildings("barbarians_market")
       end
 
       local h = plr:place_building("barbarians_citadel", sf, false, true)

=== modified file 'data/tribes/scripting/starting_conditions/barbarians/headquarters.lua'
--- data/tribes/scripting/starting_conditions/barbarians/headquarters.lua	2016-03-30 07:23:59 +0000
+++ data/tribes/scripting/starting_conditions/barbarians/headquarters.lua	2017-09-15 13:27:37 +0000
@@ -18,6 +18,7 @@
       sf = shared_in_start
    else
       player:allow_workers("all")
+      plr:forbid_buildings("barbarians_market")
    end
 
    hq = prefilled_buildings(player, { "barbarians_headquarters", sf.x, sf.y,

=== modified file 'data/tribes/scripting/starting_conditions/barbarians/trading_outpost.lua'
--- data/tribes/scripting/starting_conditions/barbarians/trading_outpost.lua	2016-11-01 13:58:24 +0000
+++ data/tribes/scripting/starting_conditions/barbarians/trading_outpost.lua	2017-09-15 13:27:37 +0000
@@ -18,6 +18,7 @@
          sf = shared_in_start
       else
          player:allow_workers("all")
+         plr:forbid_buildings("barbarians_market")
       end
 
       hq = prefilled_buildings(player, { "barbarians_headquarters", sf.x, sf.y,

=== modified file 'regression_test.py'
--- regression_test.py	2016-08-14 07:59:55 +0000
+++ regression_test.py	2017-09-15 13:27:37 +0000
@@ -217,7 +217,7 @@
     args = parse_args()
 
     WidelandsTestCase.path_to_widelands_binary = args.binary
-    print("Using '{}' binary.".format(args.binary)) 
+    print("Using '{}' binary.".format(args.binary))
     WidelandsTestCase.do_use_random_directory = not args.nonrandom
     WidelandsTestCase.keep_output_around = args.keep_around
 

=== modified file 'src/logic/CMakeLists.txt'
--- src/logic/CMakeLists.txt	2017-08-11 15:30:42 +0000
+++ src/logic/CMakeLists.txt	2017-09-15 13:27:37 +0000
@@ -166,6 +166,8 @@
     map_objects/tribes/constructionsite.h
     map_objects/tribes/dismantlesite.cc
     map_objects/tribes/dismantlesite.h
+    map_objects/tribes/market.cc
+    map_objects/tribes/market.h
     map_objects/tribes/militarysite.cc
     map_objects/tribes/militarysite.h
     map_objects/tribes/partially_finished_building.cc

=== modified file 'src/logic/map_objects/map_object.cc'
--- src/logic/map_objects/map_object.cc	2017-08-16 13:23:15 +0000
+++ src/logic/map_objects/map_object.cc	2017-09-15 13:27:37 +0000
@@ -653,6 +653,8 @@
 		return "dismantlesite";
 	case MapObjectType::WAREHOUSE:
 		return "warehouse";
+	case MapObjectType::MARKET:
+		return "market";
 	case MapObjectType::PRODUCTIONSITE:
 		return "productionsite";
 	case MapObjectType::MILITARYSITE:

=== modified file 'src/logic/map_objects/map_object.h'
--- src/logic/map_objects/map_object.h	2017-07-03 19:24:02 +0000
+++ src/logic/map_objects/map_object.h	2017-09-15 13:27:37 +0000
@@ -82,6 +82,7 @@
 	CONSTRUCTIONSITE,  // Building -- Constructionsite
 	DISMANTLESITE,     // Building -- Dismantlesite
 	WAREHOUSE,         // Building -- Warehouse
+	MARKET,            // Building -- Market
 	PRODUCTIONSITE,    // Building -- Productionsite
 	MILITARYSITE,      // Building -- Productionsite -- Militarysite
 	TRAININGSITE       // Building -- Productionsite -- Trainingsite

=== added file 'src/logic/map_objects/tribes/market.cc'
--- src/logic/map_objects/tribes/market.cc	1970-01-01 00:00:00 +0000
+++ src/logic/map_objects/tribes/market.cc	2017-09-15 13:27:37 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006-2017 by the Widelands Development Team
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "logic/map_objects/tribes/market.h"
+
+#include "base/i18n.h"
+#include "logic/map_objects/tribes/productionsite.h"
+
+namespace Widelands {
+
+MarketDescr::MarketDescr(const std::string& init_descname,
+                         const LuaTable& table,
+                         const EditorGameBase& egbase)
+   : BuildingDescr(init_descname, MapObjectType::MARKET, table, egbase) {
+	i18n::Textdomain td("tribes");
+
+	parse_working_positions(egbase, table.get_table("working_positions").get(), &working_positions_);
+	// TODO(sirver,trading): Add actual logic here.
+}
+
+Building& MarketDescr::create_object() const {
+	return *new Market(*this);
+}
+
+Market::Market(const MarketDescr& descr) : Building(descr) {}
+
+Market::~Market() {}
+
+}  // namespace Widelands

=== added file 'src/logic/map_objects/tribes/market.h'
--- src/logic/map_objects/tribes/market.h	1970-01-01 00:00:00 +0000
+++ src/logic/map_objects/tribes/market.h	2017-09-15 13:27:37 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006-2017 by the Widelands Development Team
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef WL_LOGIC_MAP_OBJECTS_TRIBES_MARKET_H
+#define WL_LOGIC_MAP_OBJECTS_TRIBES_MARKET_H
+
+#include "logic/map_objects/tribes/building.h"
+
+namespace Widelands {
+
+class MarketDescr : public BuildingDescr {
+public:
+	MarketDescr(const std::string& init_descname, const LuaTable& t, const EditorGameBase& egbase);
+	~MarketDescr() override {
+	}
+
+	Building& create_object() const override;
+
+private:
+	BillOfMaterials working_positions_;
+};
+
+class Market : public Building {
+	MO_DESCR(MarketDescr)
+public:
+	explicit Market(const MarketDescr& descr);
+	~Market() override;
+
+private:
+	DISALLOW_COPY_AND_ASSIGN(Market);
+};
+
+}  // namespace Widelands
+
+#endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_TRIBES_MARKET_H

=== modified file 'src/logic/map_objects/tribes/productionsite.cc'
--- src/logic/map_objects/tribes/productionsite.cc	2017-08-16 04:31:56 +0000
+++ src/logic/map_objects/tribes/productionsite.cc	2017-09-15 13:27:37 +0000
@@ -45,7 +45,31 @@
 
 namespace Widelands {
 
-static const size_t STATISTICS_VECTOR_LENGTH = 20;
+namespace {
+
+constexpr size_t STATISTICS_VECTOR_LENGTH = 20;
+
+}  // namespace
+
+void parse_working_positions(const EditorGameBase& egbase,
+                             LuaTable* items_table,
+                             BillOfMaterials* working_positions) {
+	for (const std::string& worker_name : items_table->keys<std::string>()) {
+		int amount = items_table->get_int(worker_name);
+		try {
+			if (amount < 1 || 255 < amount) {
+				throw wexception("count is out of range 1 .. 255");
+			}
+			DescriptionIndex const woi = egbase.tribes().worker_index(worker_name);
+			if (!egbase.tribes().worker_exists(woi)) {
+				throw wexception("invalid");
+			}
+			working_positions->push_back(std::pair<DescriptionIndex, uint32_t>(woi, amount));
+		} catch (const WException& e) {
+			throw wexception("%s=\"%d\": %s", worker_name.c_str(), amount, e.what());
+		}
+	}
+}
 
 /*
 ==============================================================================
@@ -146,28 +170,7 @@
 		}
 	}
 
-	items_table = table.get_table("working_positions");
-	for (const std::string& worker_name : items_table->keys<std::string>()) {
-		int amount = items_table->get_int(worker_name);
-		try {
-			if (amount < 1 || 255 < amount) {
-				throw wexception("count is out of range 1 .. 255");
-			}
-			DescriptionIndex const woi = egbase.tribes().worker_index(worker_name);
-			if (egbase.tribes().worker_exists(woi)) {
-				for (const auto& wp : working_positions()) {
-					if (wp.first == woi) {
-						throw wexception("duplicated");
-					}
-				}
-				working_positions_.push_back(std::pair<DescriptionIndex, uint32_t>(woi, amount));
-			} else {
-				throw wexception("invalid");
-			}
-		} catch (const WException& e) {
-			throw wexception("%s=\"%d\": %s", worker_name.c_str(), amount, e.what());
-		}
-	}
+	parse_working_positions(egbase, table.get_table("working_positions").get(), &working_positions_);
 
 	// Get programs
 	items_table = table.get_table("programs");

=== modified file 'src/logic/map_objects/tribes/productionsite.h'
--- src/logic/map_objects/tribes/productionsite.h	2017-06-24 08:47:46 +0000
+++ src/logic/map_objects/tribes/productionsite.h	2017-09-15 13:27:37 +0000
@@ -374,6 +374,15 @@
 	   : ps(init_ps), player(init_player) {
 	}
 };
-}
+
+// Parses the descriptions of the working positions from 'items_table' and
+// fills in 'working_positions'. Throws an error if the table contains invalid
+// values.
+void parse_working_positions(const EditorGameBase& egbase,
+                             LuaTable* items_table,
+                             BillOfMaterials* working_positions);
+
+}  // namespace Widelands
+
 
 #endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_TRIBES_PRODUCTIONSITE_H

=== modified file 'src/logic/map_objects/tribes/tribes.cc'
--- src/logic/map_objects/tribes/tribes.cc	2017-03-23 07:36:36 +0000
+++ src/logic/map_objects/tribes/tribes.cc	2017-09-15 13:27:37 +0000
@@ -121,6 +121,13 @@
 	   table, egbase));
 }
 
+void Tribes::add_market_type(const LuaTable& table, const EditorGameBase& egbase) {
+	i18n::Textdomain td("tribes");
+	buildings_->add(new MarketDescr(
+	   pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
+	   table, egbase));
+}
+
 void Tribes::add_immovable_type(const LuaTable& table) {
 	i18n::Textdomain td("tribes");
 	immovables_->add(new ImmovableDescr(

=== modified file 'src/logic/map_objects/tribes/tribes.h'
--- src/logic/map_objects/tribes/tribes.h	2017-03-23 07:36:36 +0000
+++ src/logic/map_objects/tribes/tribes.h	2017-09-15 13:27:37 +0000
@@ -38,6 +38,7 @@
 #include "logic/map_objects/tribes/tribe_descr.h"
 #include "logic/map_objects/tribes/ware_descr.h"
 #include "logic/map_objects/tribes/warehouse.h"
+#include "logic/map_objects/tribes/market.h"
 #include "logic/map_objects/tribes/worker_descr.h"
 #include "scripting/lua_table.h"
 
@@ -82,6 +83,9 @@
 	/// Adds this building type to the tribe description.
 	void add_warehouse_type(const LuaTable& table, const EditorGameBase& egbase);
 
+	/// Adds this building type to the tribe description.
+	void add_market_type(const LuaTable& table, const EditorGameBase& egbase);
+
 	/// Adds this immovable type to the tribe description.
 	void add_immovable_type(const LuaTable& table);
 

=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc	2017-09-03 13:03:56 +0000
+++ src/scripting/lua_map.cc	2017-09-15 13:27:37 +0000
@@ -618,6 +618,8 @@
 			return CAST_TO_LUA(MilitarySiteDescr, LuaMilitarySiteDescription);
 		case MapObjectType::WAREHOUSE:
 			return CAST_TO_LUA(WarehouseDescr, LuaWarehouseDescription);
+		case MapObjectType::MARKET:
+			return CAST_TO_LUA(MarketDescr, LuaMarketDescription);
 		case MapObjectType::TRAININGSITE:
 			return CAST_TO_LUA(TrainingSiteDescr, LuaTrainingSiteDescription);
 		default:
@@ -684,17 +686,19 @@
 		return CAST_TO_LUA(Building);
 	case MapObjectType::WAREHOUSE:
 		return CAST_TO_LUA(Warehouse);
+	case MapObjectType::MARKET:
+		return CAST_TO_LUA(Market);
 	case MapObjectType::PRODUCTIONSITE:
 		return CAST_TO_LUA(ProductionSite);
 	case MapObjectType::MILITARYSITE:
 		return CAST_TO_LUA(MilitarySite);
 	case MapObjectType::TRAININGSITE:
 		return CAST_TO_LUA(TrainingSite);
-	case (MapObjectType::MAPOBJECT):
-	case (MapObjectType::BATTLE):
-	case (MapObjectType::BOB):
-	case (MapObjectType::FLEET):
-	case (MapObjectType::WARE):
+	case MapObjectType::MAPOBJECT:
+	case MapObjectType::BATTLE:
+	case MapObjectType::BOB:
+	case MapObjectType::FLEET:
+	case MapObjectType::WARE:
 		throw LuaError((boost::format("upcasted_map_object_to_lua: Unknown %i") %
 		                static_cast<int>(mo->descr().type()))
 		                  .str());
@@ -2746,6 +2750,33 @@
 }
 
 /* RST
+MarketDescription
+--------------------
+
+.. class:: MarketDescription
+
+   Child of: :class:`MapObjectDescription`, :class:`ImmovableDescription`, :class:`BuildingDescription`
+
+	A static description of a tribe's market, so it can be used in help files
+	without having to access an actual building on the map. A Market is used for
+	trading over land with other players.
+   See the parent classes for more properties.
+*/
+const char LuaMarketDescription::className[] = "MarketDescription";
+const MethodType<LuaMarketDescription> LuaMarketDescription::Methods[] = {
+   {nullptr, nullptr},
+};
+const PropertyType<LuaMarketDescription> LuaMarketDescription::Properties[] = {
+   {nullptr, nullptr, nullptr},
+};
+
+/*
+ ==========================================================
+ PROPERTIES
+ ==========================================================
+ */
+
+/* RST
 WareDescription
 ---------------
 
@@ -3664,36 +3695,38 @@
 	assert(desc != nullptr);
 
 	switch (desc->type()) {
-	case (MapObjectType::BUILDING):
+	case MapObjectType::BUILDING:
 		return CAST_TO_LUA(BuildingDescr, LuaBuildingDescription);
-	case (MapObjectType::CONSTRUCTIONSITE):
+	case MapObjectType::CONSTRUCTIONSITE:
 		return CAST_TO_LUA(ConstructionSiteDescr, LuaConstructionSiteDescription);
-	case (MapObjectType::DISMANTLESITE):
+	case MapObjectType::DISMANTLESITE:
 		return CAST_TO_LUA(DismantleSiteDescr, LuaDismantleSiteDescription);
-	case (MapObjectType::PRODUCTIONSITE):
+	case MapObjectType::PRODUCTIONSITE:
 		return CAST_TO_LUA(ProductionSiteDescr, LuaProductionSiteDescription);
-	case (MapObjectType::MILITARYSITE):
+	case MapObjectType::MILITARYSITE:
 		return CAST_TO_LUA(MilitarySiteDescr, LuaMilitarySiteDescription);
-	case (MapObjectType::TRAININGSITE):
+	case MapObjectType::TRAININGSITE:
 		return CAST_TO_LUA(TrainingSiteDescr, LuaTrainingSiteDescription);
-	case (MapObjectType::WAREHOUSE):
+	case MapObjectType::WAREHOUSE:
 		return CAST_TO_LUA(WarehouseDescr, LuaWarehouseDescription);
-	case (MapObjectType::IMMOVABLE):
+	case MapObjectType::MARKET:
+		return CAST_TO_LUA(MarketDescr, LuaMarketDescription);
+	case MapObjectType::IMMOVABLE:
 		return CAST_TO_LUA(ImmovableDescr, LuaImmovableDescription);
-	case (MapObjectType::WORKER):
-	case (MapObjectType::CARRIER):
-	case (MapObjectType::SOLDIER):
+	case MapObjectType::WORKER:
+	case MapObjectType::CARRIER:
+	case MapObjectType::SOLDIER:
 		return CAST_TO_LUA(WorkerDescr, LuaWorkerDescription);
-	case (MapObjectType::MAPOBJECT):
-	case (MapObjectType::BATTLE):
-	case (MapObjectType::BOB):
-	case (MapObjectType::CRITTER):
-	case (MapObjectType::FLEET):
-	case (MapObjectType::SHIP):
-	case (MapObjectType::FLAG):
-	case (MapObjectType::ROAD):
-	case (MapObjectType::PORTDOCK):
-	case (MapObjectType::WARE):
+	case MapObjectType::MAPOBJECT:
+	case MapObjectType::BATTLE:
+	case MapObjectType::BOB:
+	case MapObjectType::CRITTER:
+	case MapObjectType::FLEET:
+	case MapObjectType::SHIP:
+	case MapObjectType::FLAG:
+	case MapObjectType::ROAD:
+	case MapObjectType::PORTDOCK:
+	case MapObjectType::WARE:
 		return CAST_TO_LUA(MapObjectDescr, LuaMapObjectDescription);
 	}
 	NEVER_HERE();
@@ -5036,6 +5069,51 @@
 }
 
 /* RST
+Market
+---------
+
+.. class:: Market
+
+   Child of: :class:`Building`, :class:`HasWares`, :class:`HasWorkers`
+
+	A Market used for trading with other players.
+
+   More properties are available through this object's
+   :class:`MarketDescription`, which you can access via :any:`MapObject.descr`.
+*/
+const char LuaMarket::className[] = "Market";
+const MethodType<LuaMarket> LuaMarket::Methods[] = {
+	// TODO(sirver,trading): Implement and fix documentation.
+   // METHOD(LuaMarket, set_wares),
+   // METHOD(LuaMarket, get_wares),
+   // METHOD(LuaMarket, set_workers),
+   // METHOD(LuaMarket, get_workers),
+   {nullptr, nullptr},
+};
+const PropertyType<LuaMarket> LuaMarket::Properties[] = {
+   {nullptr, nullptr, nullptr},
+};
+
+/*
+ ==========================================================
+ PROPERTIES
+ ==========================================================
+ */
+
+/*
+ ==========================================================
+ LUA METHODS
+ ==========================================================
+ */
+
+/*
+ ==========================================================
+ C METHODS
+ ==========================================================
+ */
+
+
+/* RST
 MilitarySite
 --------------
 
@@ -6362,6 +6440,11 @@
 	add_parent<LuaWarehouseDescription, LuaMapObjectDescription>(L);
 	lua_pop(L, 1);  // Pop the meta table
 
+	register_class<LuaMarketDescription>(L, "map", true);
+	add_parent<LuaMarketDescription, LuaBuildingDescription>(L);
+	add_parent<LuaMarketDescription, LuaMapObjectDescription>(L);
+	lua_pop(L, 1);  // Pop the meta table
+
 	register_class<LuaWareDescription>(L, "map", true);
 	add_parent<LuaWareDescription, LuaMapObjectDescription>(L);
 	lua_pop(L, 1);  // Pop the meta table
@@ -6450,6 +6533,13 @@
 	add_parent<LuaWarehouse, LuaMapObject>(L);
 	lua_pop(L, 1);  // Pop the meta table
 
+	register_class<LuaMarket>(L, "map", true);
+	add_parent<LuaMarket, LuaBuilding>(L);
+	add_parent<LuaMarket, LuaPlayerImmovable>(L);
+	add_parent<LuaMarket, LuaBaseImmovable>(L);
+	add_parent<LuaMarket, LuaMapObject>(L);
+	lua_pop(L, 1);  // Pop the meta table
+
 	register_class<LuaProductionSite>(L, "map", true);
 	add_parent<LuaProductionSite, LuaBuilding>(L);
 	add_parent<LuaProductionSite, LuaPlayerImmovable>(L);

=== modified file 'src/scripting/lua_map.h'
--- src/scripting/lua_map.h	2017-06-25 19:12:30 +0000
+++ src/scripting/lua_map.h	2017-09-15 13:27:37 +0000
@@ -502,6 +502,37 @@
 	CASTED_GET_DESCRIPTION(WarehouseDescr)
 };
 
+class LuaMarketDescription : public LuaBuildingDescription {
+public:
+	LUNA_CLASS_HEAD(LuaMarketDescription);
+
+	virtual ~LuaMarketDescription() {
+	}
+
+	LuaMarketDescription() {
+	}
+	explicit LuaMarketDescription(const Widelands::MarketDescr* const warehousedescr)
+	   : LuaBuildingDescription(warehousedescr) {
+	}
+	explicit LuaMarketDescription(lua_State* L) : LuaBuildingDescription(L) {
+	}
+
+	/*
+	 * Properties
+	 */
+
+	/*
+	 * Lua methods
+	 */
+
+	/*
+	 * C methods
+	 */
+
+private:
+	CASTED_GET_DESCRIPTION(MarketDescr)
+};
+
 class LuaWareDescription : public LuaMapObjectDescription {
 public:
 	LUNA_CLASS_HEAD(LuaWareDescription);
@@ -1075,6 +1106,33 @@
 	CASTED_GET(Warehouse)
 };
 
+class LuaMarket : public LuaBuilding {
+public:
+	LUNA_CLASS_HEAD(LuaMarket);
+
+	LuaMarket() {
+	}
+	explicit LuaMarket(Widelands::Market& mo) : LuaBuilding(mo) {
+	}
+	explicit LuaMarket(lua_State* L) : LuaBuilding(L) {
+	}
+	virtual ~LuaMarket() {
+	}
+
+	/*
+	 * Properties
+	 */
+
+	/*
+	 * Lua Methods
+	 */
+
+	/*
+	 * C Methods
+	 */
+	CASTED_GET(Market)
+};
+
 class LuaProductionSite : public LuaBuilding {
 public:
 	LUNA_CLASS_HEAD(LuaProductionSite);

=== modified file 'src/scripting/lua_root.cc'
--- src/scripting/lua_root.cc	2017-09-03 10:13:32 +0000
+++ src/scripting/lua_root.cc	2017-09-15 13:27:37 +0000
@@ -503,19 +503,20 @@
 
 const char LuaTribes::className[] = "Tribes";
 const MethodType<LuaTribes> LuaTribes::Methods[] = {
+   METHOD(LuaTribes, new_carrier_type),
    METHOD(LuaTribes, new_constructionsite_type),
    METHOD(LuaTribes, new_dismantlesite_type),
+   METHOD(LuaTribes, new_immovable_type),
+   METHOD(LuaTribes, new_market_type),
    METHOD(LuaTribes, new_militarysite_type),
    METHOD(LuaTribes, new_productionsite_type),
+   METHOD(LuaTribes, new_ship_type),
+   METHOD(LuaTribes, new_soldier_type),
    METHOD(LuaTribes, new_trainingsite_type),
+   METHOD(LuaTribes, new_tribe),
+   METHOD(LuaTribes, new_ware_type),
    METHOD(LuaTribes, new_warehouse_type),
-   METHOD(LuaTribes, new_immovable_type),
-   METHOD(LuaTribes, new_ship_type),
-   METHOD(LuaTribes, new_ware_type),
-   METHOD(LuaTribes, new_carrier_type),
-   METHOD(LuaTribes, new_soldier_type),
    METHOD(LuaTribes, new_worker_type),
-   METHOD(LuaTribes, new_tribe),
    {0, 0},
 };
 const PropertyType<LuaTribes> LuaTribes::Properties[] = {
@@ -691,6 +692,30 @@
 }
 
 /* RST
+	.. method:: new_market_type{table}
+
+		Adds a new market building type. Takes a single argument, a table with
+		the descriptions. See :ref:`lua_tribes_buildings_markets` for detailed
+		documentation.
+
+		:returns: :const:`0`
+*/
+int LuaTribes::new_market_type(lua_State* L) {
+	if (lua_gettop(L) != 2) {
+		report_error(L, "Takes only one argument.");
+	}
+
+	try {
+		LuaTable table(L);  // Will pop the table eventually.
+		EditorGameBase& egbase = get_egbase(L);
+		egbase.mutable_tribes()->add_market_type(table, egbase);
+	} catch (std::exception& e) {
+		report_error(L, "%s", e.what());
+	}
+	return 0;
+}
+
+/* RST
 	.. method:: new_immovable_type{table}
 
 		Adds a new immovable type. Takes a single argument, a table with

=== modified file 'src/scripting/lua_root.h'
--- src/scripting/lua_root.h	2017-06-24 08:47:46 +0000
+++ src/scripting/lua_root.h	2017-09-15 13:27:37 +0000
@@ -159,19 +159,20 @@
 	/*
 	 * Lua methods
 	 */
+	int new_carrier_type(lua_State* L);
 	int new_constructionsite_type(lua_State* L);
 	int new_dismantlesite_type(lua_State* L);
+	int new_immovable_type(lua_State* L);
+	int new_market_type(lua_State* L);
 	int new_militarysite_type(lua_State* L);
 	int new_productionsite_type(lua_State* L);
+	int new_ship_type(lua_State* L);
+	int new_soldier_type(lua_State* L);
 	int new_trainingsite_type(lua_State* L);
+	int new_tribe(lua_State* L);
+	int new_ware_type(lua_State* L);
 	int new_warehouse_type(lua_State* L);
-	int new_immovable_type(lua_State* L);
-	int new_ship_type(lua_State* L);
-	int new_ware_type(lua_State* L);
-	int new_carrier_type(lua_State* L);
-	int new_soldier_type(lua_State* L);
 	int new_worker_type(lua_State* L);
-	int new_tribe(lua_State* L);
 
 	/*
 	 * C methods

=== modified file 'src/website/map_object_info.cc'
--- src/website/map_object_info.cc	2017-01-30 14:40:12 +0000
+++ src/website/map_object_info.cc	2017-09-15 13:27:37 +0000
@@ -301,6 +301,9 @@
 		case MapObjectType::WAREHOUSE:
 			fw.write_key_value_string("type", "warehouse");
 			break;
+		case MapObjectType::MARKET:
+			fw.write_key_value_string("type", "market");
+			break;
 		case MapObjectType::MILITARYSITE:
 			fw.write_key_value_string("type", "militarysite");
 			break;

=== modified file 'src/wui/interactive_gamebase.cc'
--- src/wui/interactive_gamebase.cc	2017-08-20 17:45:42 +0000
+++ src/wui/interactive_gamebase.cc	2017-09-15 13:27:37 +0000
@@ -209,6 +209,7 @@
 			   *this, registry, *dynamic_cast<Widelands::Warehouse*>(building), avoid_fastclick);
 		};
 		break;
+		// TODO(sirver,trading): Add UI for market.
 	default:
 		log("Unable to show window for building '%s', type '%s'.\n", building->descr().name().c_str(),
 		    to_string(building->descr().type()).c_str());

=== added directory 'test/maps/market_trading.wmf'
=== added directory 'test/maps/market_trading.wmf/binary'
=== added file 'test/maps/market_trading.wmf/binary/heights'
Binary files test/maps/market_trading.wmf/binary/heights	1970-01-01 00:00:00 +0000 and test/maps/market_trading.wmf/binary/heights	2017-09-15 13:27:37 +0000 differ
=== added file 'test/maps/market_trading.wmf/binary/mapobjects'
Binary files test/maps/market_trading.wmf/binary/mapobjects	1970-01-01 00:00:00 +0000 and test/maps/market_trading.wmf/binary/mapobjects	2017-09-15 13:27:37 +0000 differ
=== added file 'test/maps/market_trading.wmf/binary/resource'
Binary files test/maps/market_trading.wmf/binary/resource	1970-01-01 00:00:00 +0000 and test/maps/market_trading.wmf/binary/resource	2017-09-15 13:27:37 +0000 differ
=== added file 'test/maps/market_trading.wmf/binary/terrain'
Binary files test/maps/market_trading.wmf/binary/terrain	1970-01-01 00:00:00 +0000 and test/maps/market_trading.wmf/binary/terrain	2017-09-15 13:27:37 +0000 differ
=== added file 'test/maps/market_trading.wmf/elemental'
--- test/maps/market_trading.wmf/elemental	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/elemental	2017-09-15 13:27:37 +0000
@@ -0,0 +1,12 @@
+# Automatically created by Widelands  (Release)
+
+[global]
+packet_version="1"
+map_w="64"
+map_h="64"
+nr_players="2"
+name="market_trading"
+author="SirVer"
+descr="no description defined"
+hint=
+tags=

=== added file 'test/maps/market_trading.wmf/minimap.png'
Binary files test/maps/market_trading.wmf/minimap.png	1970-01-01 00:00:00 +0000 and test/maps/market_trading.wmf/minimap.png	2017-09-15 13:27:37 +0000 differ
=== added file 'test/maps/market_trading.wmf/objective'
--- test/maps/market_trading.wmf/objective	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/objective	2017-09-15 13:27:37 +0000
@@ -0,0 +1,4 @@
+# Automatically created by Widelands  (Release)
+
+[global]
+packet_version="2"

=== added file 'test/maps/market_trading.wmf/player_names'
--- test/maps/market_trading.wmf/player_names	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/player_names	2017-09-15 13:27:37 +0000
@@ -0,0 +1,16 @@
+# Automatically created by Widelands  (Release)
+
+[global]
+packet_version="2"
+
+[player_1]
+name="Player 1"
+tribe="barbarians"
+ai="empty"
+closeable="false"
+
+[player_2]
+name="Player 2"
+tribe="barbarians"
+ai="empty"
+closeable="false"

=== added file 'test/maps/market_trading.wmf/player_position'
--- test/maps/market_trading.wmf/player_position	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/player_position	2017-09-15 13:27:37 +0000
@@ -0,0 +1,6 @@
+# Automatically created by Widelands  (Release)
+
+[global]
+packet_version="2"
+player_1="21 27"
+player_2="45 27"

=== added file 'test/maps/market_trading.wmf/port_spaces'
--- test/maps/market_trading.wmf/port_spaces	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/port_spaces	2017-09-15 13:27:37 +0000
@@ -0,0 +1,7 @@
+# Automatically created by Widelands  (Release)
+
+[global]
+packet_version="1"
+number_of_port_spaces="0"
+
+[port_spaces]

=== added directory 'test/maps/market_trading.wmf/scripting'
=== added file 'test/maps/market_trading.wmf/scripting/init.lua'
--- test/maps/market_trading.wmf/scripting/init.lua	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/scripting/init.lua	2017-09-15 13:27:37 +0000
@@ -0,0 +1,28 @@
+include "scripting/lunit.lua"
+include "scripting/coroutine.lua"
+include "scripting/infrastructure.lua"
+include "scripting/ui.lua"
+
+game = wl.Game()
+map = game.map
+p1 = game.players[1]
+p2 = game.players[2]
+p1.see_all = true
+
+p1:allow_workers("all")
+
+function full_headquarters(player, x, y) 
+   prefilled_buildings(player, { "barbarians_headquarters", x, y })
+   hq = player:get_buildings("barbarians_headquarters")[1]
+   for idx,descr in ipairs(game:get_tribe_description("barbarians").wares) do
+      hq:set_wares(descr.name, 350)
+   end
+   for idx,descr in ipairs(game:get_tribe_description("barbarians").workers) do
+      hq:set_workers(descr.name, 50)
+   end
+end
+
+full_headquarters(p1, 22, 25)
+full_headquarters(p2, 32, 25)
+
+game.desired_speed = 50000

=== added file 'test/maps/market_trading.wmf/scripting/test_market_can_be_build.lua'
--- test/maps/market_trading.wmf/scripting/test_market_can_be_build.lua	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/scripting/test_market_can_be_build.lua	2017-09-15 13:27:37 +0000
@@ -0,0 +1,13 @@
+run(function()
+   sleep(2000)
+
+   market = p2:place_building("barbarians_market", map:get_field(35, 25), true, true)
+   connected_road(p2, market.flag, "l,l,l|", true)
+
+   while #p2:get_buildings("barbarians_market") == 0 do
+      sleep(10000)
+   end
+   print("# All Tests passed.")
+   wl.ui.MapView():close()
+end)
+

=== added file 'test/maps/market_trading.wmf/version'
--- test/maps/market_trading.wmf/version	1970-01-01 00:00:00 +0000
+++ test/maps/market_trading.wmf/version	2017-09-15 13:27:37 +0000
@@ -0,0 +1,11 @@
+# Automatically created by Widelands  (Release)
+
+[global]
+map_source_url=
+map_release=
+map_creator_version=
+map_version_major="0"
+map_version_minor="1"
+map_version_timestamp="1505478312"
+packet_version="1"
+packet_compatibility="1"


References