widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #06379
[Merge] lp:~widelands-dev/widelands/map_object_info into lp:widelands
GunChleoc has proposed merging lp:~widelands-dev/widelands/map_object_info into lp:widelands.
Commit message:
Created a new executable that will generate JSON files for updating the e3ncyclopedia on the website.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #350465 in widelands: "online_help returns false information"
https://bugs.launchpad.net/widelands/+bug/350465
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/map_object_info/+merge/287409
Created a new executable that will generate JSON files for updating the encyclopedia on the website.
I recommend that we wait with merging this when we get close to the release candidate, because we now have extra linking time with each compile.
Related website branch:
https://code.launchpad.net/~widelands-dev/widelands-website/encyclopedia
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/map_object_info into lp:widelands.
=== modified file '.bzrignore'
--- .bzrignore 2016-01-02 12:36:38 +0000
+++ .bzrignore 2016-02-28 18:20:27 +0000
@@ -21,3 +21,4 @@
# OS-X Meta Files
.DS_Store
+data/map_object_info
=== added directory 'data/tribes/scripting/mapobject_info'
=== added file 'data/tribes/scripting/mapobject_info/building_helptext.lua'
--- data/tribes/scripting/mapobject_info/building_helptext.lua 1970-01-01 00:00:00 +0000
+++ data/tribes/scripting/mapobject_info/building_helptext.lua 2016-02-28 18:20:27 +0000
@@ -0,0 +1,9 @@
+-- This is used by the mapinfo standalone executable to get buildings' helptexts.
+-- Note that this can't handle localization properly.
+
+return {
+ func = function(building_description)
+ include(building_description.helptext_script)
+ return building_helptext_purpose()
+ end
+}
=== added file 'data/tribes/scripting/mapobject_info/ware_helptext.lua'
--- data/tribes/scripting/mapobject_info/ware_helptext.lua 1970-01-01 00:00:00 +0000
+++ data/tribes/scripting/mapobject_info/ware_helptext.lua 2016-02-28 18:20:27 +0000
@@ -0,0 +1,9 @@
+-- This is used by the mapinfo standalone executable to get wares' helptexts.
+-- Note that this can't handle localization properly.
+
+return {
+ func = function(tribename, ware_description)
+ include(ware_description.helptext_script)
+ return ware_helptext(tribename)
+ end
+}
=== added file 'data/tribes/scripting/mapobject_info/worker_helptext.lua'
--- data/tribes/scripting/mapobject_info/worker_helptext.lua 1970-01-01 00:00:00 +0000
+++ data/tribes/scripting/mapobject_info/worker_helptext.lua 2016-02-28 18:20:27 +0000
@@ -0,0 +1,9 @@
+-- This is used by the mapinfo standalone executable to get workers' helptexts.
+-- Note that this can't handle localization properly.
+
+return {
+ func = function(worker_description)
+ include(worker_description.helptext_script)
+ return worker_helptext()
+ end
+}
=== modified file 'debian/widelands.install'
--- debian/widelands.install 2016-01-22 07:20:01 +0000
+++ debian/widelands.install 2016-02-28 18:20:27 +0000
@@ -1,5 +1,6 @@
usr/widelands usr/games
usr/wl_map_info usr/games
+usr/wl_mapobject_info usr/games
usr/wl_render_richtext usr/games
usr/share/applications
usr/share/icons
=== modified file 'src/logic/CMakeLists.txt'
--- src/logic/CMakeLists.txt 2016-01-18 19:35:25 +0000
+++ src/logic/CMakeLists.txt 2016-02-28 18:20:27 +0000
@@ -14,6 +14,21 @@
map_io_map_loader
)
+wl_binary(wl_map_object_info
+ SRCS
+ map_objects/map_object_info.cc
+ USES_SDL2
+ DEPENDS
+ base_i18n
+ base_log
+ base_macros
+ graphic
+ io_fileread
+ io_filesystem
+ logic
+ sound
+)
+
wl_library(logic_widelands_geometry
SRCS
widelands_geometry.cc
=== modified file 'src/logic/map_objects/immovable.cc'
--- src/logic/map_objects/immovable.cc 2016-02-18 08:42:46 +0000
+++ src/logic/map_objects/immovable.cc 2016-02-28 18:20:27 +0000
@@ -61,9 +61,11 @@
namespace Widelands {
-namespace {
+BaseImmovable::BaseImmovable(const MapObjectDescr & mo_descr) :
+MapObject(&mo_descr)
+{}
-BaseImmovable::Size string_to_size(const std::string& size) {
+int32_t BaseImmovable::string_to_size(const std::string& size) {
if (size == "none")
return BaseImmovable::NONE;
if (size == "small")
@@ -75,13 +77,20 @@
throw GameDataError("Unknown size %s.", size.c_str());
}
-} // namespace
-
-
-BaseImmovable::BaseImmovable(const MapObjectDescr & mo_descr) :
-MapObject(&mo_descr)
-{}
-
+std::string BaseImmovable::size_to_string(int32_t size) {
+ switch (size) {
+ case BaseImmovable::NONE:
+ return "none";
+ case BaseImmovable::SMALL:
+ return "small";
+ case BaseImmovable::MEDIUM:
+ return "medium";
+ case BaseImmovable::BIG:
+ return "big";
+ default:
+ NEVER_HERE();
+ }
+}
static std::string const base_immovable_name = "unknown";
@@ -206,7 +215,7 @@
}
if (table.has_key("size")) {
- size_ = string_to_size(table.get_string("size"));
+ size_ = BaseImmovable::string_to_size(table.get_string("size"));
}
if (table.has_key("terrain_affinity")) {
=== modified file 'src/logic/map_objects/immovable.h'
--- src/logic/map_objects/immovable.h 2016-02-10 19:50:13 +0000
+++ src/logic/map_objects/immovable.h 2016-02-28 18:20:27 +0000
@@ -96,6 +96,9 @@
(const EditorGameBase &, RenderTarget &, const FCoords&, const Point&)
= 0;
+ static int32_t string_to_size(const std::string& size);
+ static std::string size_to_string(int32_t size);
+
protected:
void set_position(EditorGameBase &, Coords);
void unset_position(EditorGameBase &, Coords);
=== added file 'src/logic/map_objects/map_object_info.cc'
--- src/logic/map_objects/map_object_info.cc 1970-01-01 00:00:00 +0000
+++ src/logic/map_objects/map_object_info.cc 2016-02-28 18:20:27 +0000
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2016 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 <memory>
+
+#include <SDL.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include "base/i18n.h"
+#include "base/log.h"
+#include "base/macros.h"
+#include "config.h"
+#include "graphic/graphic.h"
+#include "io/filesystem/filesystem.h"
+#include "io/filesystem/layered_filesystem.h"
+#include "io/filewrite.h"
+#include "logic/editor_game_base.h"
+#include "logic/map_objects/tribes/tribes.h"
+#include "logic/map_objects/world/world.h"
+#include "sound/sound_handler.h"
+
+using namespace Widelands;
+
+namespace {
+
+/*
+ ==========================================================
+ SETUP
+ ==========================================================
+ */
+
+const std::string kDirectory = "map_object_info";
+
+// Setup the static objects Widelands needs to operate and initializes systems.
+void initialize() {
+ i18n::set_locale("en");
+
+ if (SDL_Init(SDL_INIT_VIDEO) != 0) {
+ throw wexception("Unable to initialize SDL: %s", SDL_GetError());
+ }
+
+ g_fs = new LayeredFileSystem();
+ g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR));
+ g_fs->ensure_directory_exists(kDirectory);
+
+ // We don't really need graphics or sound here, but we will get error messages
+ // when they aren't initialized
+ g_gr = new Graphic();
+ g_gr->initialize(Graphic::TraceGl::kNo, 1, 1, false);
+
+ g_sound_handler.init();
+ g_sound_handler.nosound_ = true;
+}
+
+/*
+ ==========================================================
+ SPECIALIZED FILEWRITE
+ ==========================================================
+ */
+
+// Defines some convenience writing functions for the JSOn format
+class JSONFileWrite : public FileWrite {
+public:
+ JSONFileWrite() : FileWrite(), level_(0) {}
+
+ void write_string(const std::string& s, bool use_indent = false) {
+ std::string writeme = s;
+ if (use_indent) {
+ for (int i = 0; i < level_; ++i) {
+ writeme = (boost::format(" %s") % writeme).str();
+ }
+ }
+ data(writeme.c_str(), writeme.size());
+ }
+ void write_key(const std::string& key) {
+ write_string((boost::format("\"%s\":\n") % key).str(), true);
+ }
+ void write_value_string(const std::string& quoted_value) {
+ write_string((boost::format("\"%s\"") % quoted_value).str(), true);
+ }
+ void write_key_value(const std::string& key, const std::string& quoted_value) {
+ write_string((boost::format("\"%s\": %s") % key % quoted_value).str(), true);
+ }
+ void write_key_value_string(const std::string& key, const std::string& value) {
+ std::string quoted_value = value;
+ boost::replace_all(quoted_value, "\"", "\\\"");
+ write_key_value(key, "\"" + value + "\"");
+ }
+ void write_key_value_int(const std::string& key, const int value) {
+ write_key_value(key, boost::lexical_cast<std::string>(value));
+ }
+ void open_brace() {
+ write_string("{\n", true);
+ ++level_;
+ }
+ // JSON hates a final comma. This defaults to having NO comma.
+ void close_brace(bool precede_newline = false, int current = 0, int total = 0) {
+ --level_;
+ if (precede_newline) {
+ write_string("\n");
+ }
+ if (current < total - 1) {
+ write_string("},\n", true);
+ } else {
+ write_string("}", true);
+ }
+ }
+ void open_array(const std::string& name) {
+ write_string((boost::format("\"%s\":[\n") % name).str(), true);
+ ++level_;
+ }
+ // JSON hates a final comma. This defaults to having NO comma.
+ void close_array(int current = 0, int total = 0) {
+ --level_;
+ write_string("\n");
+ if (current < total - 1) {
+ write_string("],\n", true);
+ } else {
+ write_string("]\n", true);
+ }
+ }
+ // JSON hates a final comma. This defaults to having a comma.
+ void close_element(int current = -2, int total = 0) {
+ if (current < total - 1) {
+ write_string(",\n");
+ }
+ }
+private:
+ int level_;
+};
+
+/*
+ ==========================================================
+ BUILDINGS
+ ==========================================================
+ */
+
+void write_buildings(const TribeDescr& tribe, EditorGameBase& egbase) {
+
+ log("\n==================\nWriting buildings:\n==================\n");
+ JSONFileWrite fw;
+ fw.open_brace(); // Main
+ fw.open_array("buildings"); // Buildings
+
+ // We don't want any partially finished buildings
+ std::vector<const BuildingDescr*> buildings;
+ for (const DescriptionIndex& index : tribe.buildings()) {
+ const BuildingDescr* building = tribe.get_building_descr(index);
+ if (building->type() != MapObjectType::CONSTRUCTIONSITE &&
+ building->type() != MapObjectType::DISMANTLESITE) {
+ buildings.push_back(building);
+ }
+ }
+
+ // Now write
+ for (size_t i = 0; i < buildings.size(); ++i) {
+ const BuildingDescr& building = *buildings[i];
+ log(" %s", building.name().c_str());
+ fw.open_brace(); // Building
+
+ fw.write_key_value_string("name", building.name());
+ fw.close_element();
+ fw.write_key_value_string("descname", building.descname());
+ fw.close_element();
+ fw.write_key_value_string("icon", building.representative_image_filename());
+ fw.close_element();
+
+ // Conditional stuff in between, so we won't run into trouble with the commas.
+
+ // Buildcost
+ if (building.is_buildable()) {
+ fw.open_array("buildcost"); // Buildcost
+ size_t buildcost_counter = 0;
+ for (WareAmount buildcost : building.buildcost()) {
+ const WareDescr& ware = *tribe.get_ware_descr(buildcost.first);
+ fw.open_brace(); // Buildcost
+ fw.write_key_value_string("name", ware.name());
+ fw.close_element();
+ fw.write_key_value_int("amount", buildcost.second);
+ fw.close_brace(true, buildcost_counter, building.buildcost().size()); // Buildcost
+ ++buildcost_counter;
+ }
+ fw.close_array(1, 5); // Buildcost - we need a comma
+ }
+
+ if (building.is_enhanced()) {
+ fw.write_key_value_string("enhanced", tribe.get_building_descr(building.enhanced_from())->name());
+ fw.close_element();
+ }
+
+ if (building.enhancement() != INVALID_INDEX) {
+ fw.write_key_value_string("enhancement", tribe.get_building_descr(building.enhancement())->name());
+ fw.close_element();
+ }
+
+ if (upcast(ProductionSiteDescr const, productionsite, &building)) {
+ // Produces
+ if (productionsite->output_ware_types().size() > 0) {
+ fw.open_array("produced_wares"); // Produces
+ size_t produces_counter = 0;
+ for (DescriptionIndex ware_index : productionsite->output_ware_types()) {
+ fw.write_value_string(tribe.get_ware_descr(ware_index)->name());
+ fw.close_element(produces_counter, productionsite->output_ware_types().size());
+ ++produces_counter;
+ }
+ fw.close_array(1, 5); // Produces - we need a comma
+ }
+ if (productionsite->output_worker_types().size() > 0) {
+ fw.open_array("produced_workers"); // Produces
+ size_t produces_counter = 0;
+ for (DescriptionIndex worker_index : productionsite->output_worker_types()) {
+ fw.write_value_string(tribe.get_worker_descr(worker_index)->name());
+ fw.close_element(produces_counter, productionsite->output_worker_types().size());
+ ++produces_counter;
+ }
+ fw.close_array(1, 5); // Produces - we need a comma
+ }
+
+ // Consumes
+ if (productionsite->inputs().size() > 0) {
+ fw.open_array("stored_wares"); // Consumes
+ size_t consumes_counter = 0;
+ for (WareAmount input : productionsite->inputs()) {
+ const WareDescr& ware = *tribe.get_ware_descr(input.first);
+ fw.open_brace(); // Input
+ fw.write_key_value_string("name", ware.name());
+ fw.close_element();
+ fw.write_key_value_int("amount", input.second);
+ fw.close_brace(true, consumes_counter, productionsite->inputs().size()); // Input
+ ++consumes_counter;
+ }
+ fw.close_array(1, 5); // Consumes - we need a comma
+ }
+
+ fw.open_array("workers"); // Workers
+ size_t worker_counter = 0;
+ for (WareAmount input : productionsite->working_positions()) {
+ const WorkerDescr& worker = *tribe.get_worker_descr(input.first);
+ fw.open_brace(); // Worker
+ fw.write_key_value_string("name", worker.name());
+ fw.close_element();
+ fw.write_key_value_int("amount", input.second);
+ fw.close_brace(true, worker_counter, productionsite->working_positions().size()); // Worker
+ ++worker_counter;
+ }
+ fw.close_array(1, 5); // Workers - we need a comma
+ } else if (upcast(MilitarySiteDescr const, militarysite, &building)) {
+ fw.write_key_value_int("conquers", militarysite->get_conquers());
+ fw.close_element();
+ fw.write_key_value_int("max_soldiers", militarysite->get_max_number_of_soldiers());
+ fw.close_element();
+ fw.write_key_value_int("heal_per_second", militarysite->get_heal_per_second());
+ fw.close_element();
+ }
+
+ switch (building.type()) {
+ case MapObjectType::PRODUCTIONSITE:
+ fw.write_key_value_string("type", "productionsite");
+ break;
+ case MapObjectType::WAREHOUSE:
+ fw.write_key_value_string("type", "warehouse");
+ break;
+ case MapObjectType::MILITARYSITE:
+ fw.write_key_value_string("type", "militarysite");
+ break;
+ case MapObjectType::TRAININGSITE:
+ fw.write_key_value_string("type", "trainingsite");
+ break;
+ default:
+ NEVER_HERE();
+ }
+ fw.close_element();
+
+ // Size
+ if (building.type() == MapObjectType::WAREHOUSE &&
+ !building.is_buildable() && !building.is_enhanced()) {
+ fw.write_key_value_string("size", "headquarters");
+ } else if (building.get_ismine()) {
+ fw.write_key_value_string("size", "mine");
+ } else if (building.get_isport()) {
+ fw.write_key_value_string("size", "port");
+ } else {
+ fw.write_key_value_string("size", BaseImmovable::size_to_string(building.get_size()));
+ }
+ fw.close_element();
+
+ // Helptext
+ try {
+ std::unique_ptr<LuaTable> table(
+ egbase.lua().run_script("tribes/scripting/mapobject_info/building_helptext.lua"));
+ std::unique_ptr<LuaCoroutine> cr(table->get_coroutine("func"));
+ cr->push_arg(&building);
+ cr->resume();
+ const std::string help_text = cr->pop_string();
+ fw.write_key_value_string("helptext", help_text);
+ } catch (LuaError& err) {
+ fw.write_key_value_string("helptext", err.what());
+ }
+
+ fw.close_brace(true, i, buildings.size()); // Building
+ }
+ fw.close_array(); // Buildings
+ fw.close_brace(); // Main
+ fw.write(*g_fs, (boost::format("%s/%s_buildings.json") % kDirectory % tribe.name()).str().c_str());
+ log("\n");
+}
+
+/*
+ ==========================================================
+ WARES
+ ==========================================================
+ */
+
+void write_wares(const TribeDescr& tribe, EditorGameBase& egbase) {
+ log("\n===============\nWriting wares:\n===============\n");
+ JSONFileWrite fw;
+ fw.open_brace(); // Main
+
+ fw.open_array("wares"); // Wares
+ size_t counter = 0;
+ const size_t no_of_wares = tribe.wares().size();
+ for (DescriptionIndex ware_index : tribe.wares()) {
+ const WareDescr& ware = *tribe.get_ware_descr(ware_index);
+ log(" %s", ware.name().c_str());
+ fw.open_brace();
+ fw.write_key_value_string("name", ware.name());
+ fw.close_element();
+ fw.write_key_value_string("descname", ware.descname());
+ fw.close_element();
+ fw.write_key_value_string("icon", ware.icon_filename());
+ fw.close_element();
+
+ // Helptext
+ try {
+ std::unique_ptr<LuaTable> table(
+ egbase.lua().run_script("tribes/scripting/mapobject_info/ware_helptext.lua"));
+ std::unique_ptr<LuaCoroutine> cr(table->get_coroutine("func"));
+ cr->push_arg(tribe.name());
+ cr->push_arg(&ware);
+ cr->resume();
+ const std::string help_text = cr->pop_string();
+ fw.write_key_value_string("helptext", help_text);
+ } catch (LuaError& err) {
+ fw.write_key_value_string("helptext", err.what());
+ }
+ fw.close_brace(true, counter, no_of_wares); // Ware
+ ++counter;
+ }
+ fw.close_array(); // Wares
+
+ fw.close_brace(); // Main
+ fw.write(*g_fs, (boost::format("%s/%s_wares.json") % kDirectory % tribe.name()).str().c_str());
+ log("\n");
+}
+
+/*
+ ==========================================================
+ WORKERS
+ ==========================================================
+ */
+
+void write_workers(const TribeDescr& tribe, EditorGameBase& egbase) {
+ log("\n================\nWriting workers:\n================\n");
+ JSONFileWrite fw;
+ fw.open_brace(); // Main
+
+ fw.open_array("workers"); // Workers
+ size_t counter = 0;
+ const size_t no_of_workers = tribe.workers().size();
+ for (DescriptionIndex worker_index : tribe.workers()) {
+ const WorkerDescr& worker = *tribe.get_worker_descr(worker_index);
+ log(" %s", worker.name().c_str());
+ fw.open_brace();
+ fw.write_key_value_string("name", worker.name());
+ fw.close_element();
+ fw.write_key_value_string("descname", worker.descname());
+ fw.close_element();
+ fw.write_key_value_string("icon", worker.icon_filename());
+ fw.close_element();
+
+ // Helptext
+ try {
+ std::unique_ptr<LuaTable> table(
+ egbase.lua().run_script("tribes/scripting/mapobject_info/worker_helptext.lua"));
+ std::unique_ptr<LuaCoroutine> cr(table->get_coroutine("func"));
+ cr->push_arg(&worker);
+ cr->resume();
+ const std::string help_text = cr->pop_string();
+ fw.write_key_value_string("helptext", help_text);
+ } catch (LuaError& err) {
+ fw.write_key_value_string("helptext", err.what());
+ }
+
+ if (worker.becomes() != INVALID_INDEX) {
+ fw.close_element();
+ const WorkerDescr& becomes = *tribe.get_worker_descr(worker.becomes());
+ fw.write_key("becomes");
+ fw.open_brace();
+ fw.write_key_value_string("name", becomes.name());
+ fw.close_element();
+ fw.write_key_value_int("experience", worker.get_needed_experience());
+ fw.close_brace(true);
+ }
+ fw.close_brace(true, counter, no_of_workers); // Worker
+ ++counter;
+ }
+ fw.close_array(); // Workers
+
+ fw.close_brace(); // Main
+ fw.write(*g_fs, (boost::format("%s/%s_workers.json") % kDirectory % tribe.name()).str().c_str());
+ log("\n");
+}
+
+/*
+ ==========================================================
+ TRIBES
+ ==========================================================
+ */
+
+void add_tribe_info(const TribeBasicInfo& tribe_info, JSONFileWrite* fw) {
+ fw->write_key_value_string("name", tribe_info.name);
+ fw->close_element();
+ fw->write_key_value_string("descname", tribe_info.descname);
+ fw->close_element();
+ fw->write_key_value_string("author", tribe_info.author);
+ fw->close_element();
+ fw->write_key_value_string("tooltip", tribe_info.tooltip);
+ fw->close_element();
+ fw->write_key_value_string("icon", tribe_info.icon);
+}
+
+void write_tribes(EditorGameBase& egbase) {
+ JSONFileWrite fw;
+ fw.open_brace(); // Main
+ fw.open_array("tribes"); // Tribes
+
+ /// Tribes
+ egbase.mutable_tribes()->postload(); // Make sure that all values have been set.
+ const Tribes& tribes = egbase.tribes();
+
+ std::vector<TribeBasicInfo> tribeinfos = tribes.get_all_tribeinfos();
+ for (size_t tribe_index = 0; tribe_index < tribeinfos.size(); ++tribe_index) {
+ const TribeBasicInfo& tribe_info = tribeinfos[tribe_index];
+ log("\n\n=========================\nWriting tribe: %s\n=========================\n",
+ tribe_info.name.c_str());
+
+ fw.open_brace(); // TribeDescr
+ add_tribe_info(tribe_info, &fw);
+ fw.close_brace(true, tribe_index, tribeinfos.size()); // TribeDescr
+
+ // These go in separate files
+
+ JSONFileWrite fw_tribe;
+ fw_tribe.open_brace(); // TribeDescr
+ add_tribe_info(tribe_info, &fw_tribe);
+ fw_tribe.close_brace(true); // TribeDescr
+ fw_tribe.write(*g_fs, (boost::format("%s/tribe_%s.json") % kDirectory % tribe_info.name).str().c_str());
+
+ const TribeDescr& tribe =
+ *tribes.get_tribe_descr(tribes.tribe_index(tribe_info.name));
+
+ write_buildings(tribe, egbase);
+ write_wares(tribe, egbase);
+ write_workers(tribe, egbase);
+ }
+ fw.close_array(); // Tribes
+ fw.close_brace(); // Main
+ fw.write(*g_fs, (boost::format("%s/tribes.json") % kDirectory).str().c_str());
+}
+
+} // namespace
+
+/*
+ ==========================================================
+ MAIN
+ ==========================================================
+ */
+
+int main()
+{
+
+ try {
+
+ initialize();
+
+ EditorGameBase egbase(nullptr);
+ write_tribes(egbase);
+ }
+ catch (std::exception& e) {
+ log("Exception: %s.\n", e.what());
+ g_sound_handler.shutdown();
+ return 1;
+ }
+ g_sound_handler.shutdown();
+ return 0;
+}
=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc 2016-02-18 08:42:46 +0000
+++ src/scripting/lua_map.cc 2016-02-28 18:20:27 +0000
@@ -1559,20 +1559,9 @@
* :const:`big` -- Example: Big sized buildings or rocks
*/
int LuaImmovableDescription::get_size(lua_State * L) {
- switch (get()->get_size()) {
- case BaseImmovable::NONE:
- lua_pushstring(L, "none");
- break;
- case BaseImmovable::SMALL:
- lua_pushstring(L, "small");
- break;
- case BaseImmovable::MEDIUM:
- lua_pushstring(L, "medium");
- break;
- case BaseImmovable::BIG:
- lua_pushstring(L, "big");
- break;
- default:
+ try {
+ lua_pushstring(L, BaseImmovable::size_to_string(get()->get_size()));
+ } catch (std::exception&) {
report_error(L, "Unknown size %i in LuaImmovableDescription::get_size: %s",
get()->get_size(), get()->name().c_str());
}
@@ -1818,17 +1807,9 @@
* :const:`big` -- Big sized buildings
*/
int LuaBuildingDescription::get_size(lua_State * L) {
- switch (get()->get_size()) {
- case BaseImmovable::SMALL:
- lua_pushstring(L, "small");
- break;
- case BaseImmovable::MEDIUM:
- lua_pushstring(L, "medium");
- break;
- case BaseImmovable::BIG:
- lua_pushstring(L, "big");
- break;
- default:
+ try {
+ lua_pushstring(L, BaseImmovable::size_to_string(get()->get_size()));
+ } catch (std::exception&) {
report_error(L, "Unknown size %i in LuaBuildingDescription::get_size: %s",
get()->get_size(), get()->name().c_str());
}
=== added file 'utils/validate_json.py'
--- utils/validate_json.py 1970-01-01 00:00:00 +0000
+++ utils/validate_json.py 2016-02-28 18:20:27 +0000
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+import codecs
+import json
+import os.path
+import sys
+
+# Tests if .json files in data/map_object_info are valid JSON files
+
+def validate_files_in_path(source_path):
+
+ if (not os.path.isdir(source_path)):
+ print("Error: Path " + source_path + " not found.")
+ sys.exit(1)
+
+ source_files = sorted(os.listdir(source_path), key=str.lower)
+
+ print("Reading JSON files in:\n " + source_path)
+ failed = 0
+ for source_filename in source_files:
+ file_path = source_path + "/" + source_filename
+ if source_filename.endswith(".json"):
+ source_file = open(file_path, "r")
+ try:
+ dataset = json.load(source_file)
+ except ValueError as err:
+ failed = failed + 1
+ print("\n Error reading " + source_filename + ":");
+ print(" " + str(err))
+
+ if failed == 0:
+ print("\nAll JSON files are OK.")
+ else:
+ if failed == 1:
+ print("\n" + str(failed) + " file is not valid JSON!");
+ else:
+ print("\n" + str(failed) + " files are not valid JSON!");
+ return failed < 1
+
+base_path = os.path.abspath(os.path.join(os.path.dirname(__file__),os.path.pardir))
+
+success = validate_files_in_path(os.path.normpath(base_path + "/data/map_object_info"))
+success = success and validate_files_in_path(os.path.normpath(base_path + "/data/txts"))
+
+if success:
+ sys.exit(0)
+else:
+ sys.exit(1)
Follow ups