← Back to team overview

widelands-dev team mailing list archive

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

 

Benedikt Straub has proposed merging lp:~widelands-dev/widelands/campaign_data into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/campaign_data/+merge/343783

Adds two Lua functions save_campaign_data() and read_campaign_data() as functions of EditorGameBase.
These functions allow a campaign to store information in a file at the end of one scenario, and read it again in another mission.
Campaign data is stored in ".widelands/campaigns/campaign_name/scenario_name.wcd".

A script can call these functions like this:
  wl.Game().save_campaign_data("frisians", "fri03", "Hello World")
  local text = wl.Game().read_campaign_data("frisians", "fri03") --> "Hello World"
  local text = wl.Game().read_campaign_data("non-existant", "xyz") --> nil
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/campaign_data into lp:widelands.
=== modified file 'src/logic/filesystem_constants.h'
--- src/logic/filesystem_constants.h	2018-04-07 16:59:00 +0000
+++ src/logic/filesystem_constants.h	2018-04-23 08:10:54 +0000
@@ -54,6 +54,10 @@
 // Default autosave interval in minutes
 constexpr int kDefaultAutosaveInterval = 15;
 
+// Filesystem names for campaign data
+const std::string kCampaignDataDir = "campaigns";
+const std::string kCampaignDataExtension = ".wcd";
+
 /// Filesystem names for screenshots
 const std::string kScreenshotsDir = "screenshots";
 

=== modified file 'src/scripting/CMakeLists.txt'
--- src/scripting/CMakeLists.txt	2017-11-20 13:50:51 +0000
+++ src/scripting/CMakeLists.txt	2018-04-23 08:10:54 +0000
@@ -115,6 +115,7 @@
     logic_tribe_basic_info
     logic_widelands_geometry
     map_io
+    profile
     scripting_base
     scripting_coroutine
     scripting_errors

=== modified file 'src/scripting/lua_bases.cc'
--- src/scripting/lua_bases.cc	2018-04-07 16:59:00 +0000
+++ src/scripting/lua_bases.cc	2018-04-23 08:10:54 +0000
@@ -19,15 +19,21 @@
 
 #include "scripting/lua_bases.h"
 
+#include <memory>
+
+#include <boost/algorithm/string.hpp>
 #include <boost/format.hpp>
 
 #include "economy/economy.h"
+#include "io/filesystem/layered_filesystem.h"
+#include "logic/filesystem_constants.h"
 #include "logic/map_objects/checkstep.h"
 #include "logic/map_objects/tribes/tribe_descr.h"
 #include "logic/map_objects/tribes/tribes.h"
 #include "logic/map_objects/tribes/ware_descr.h"
 #include "logic/map_objects/world/world.h"
 #include "logic/player.h"
+#include "profile/profile.h"
 #include "scripting/factory.h"
 #include "scripting/globals.h"
 #include "scripting/lua_map.h"
@@ -83,6 +89,8 @@
    METHOD(LuaEditorGameBase, get_worker_description),
    METHOD(LuaEditorGameBase, get_resource_description),
    METHOD(LuaEditorGameBase, get_terrain_description),
+   METHOD(LuaEditorGameBase, save_campaign_data),
+   METHOD(LuaEditorGameBase, read_campaign_data),
    {nullptr, nullptr},
 };
 const PropertyType<LuaEditorGameBase> LuaEditorGameBase::Properties[] = {
@@ -319,6 +327,91 @@
 	return to_lua<LuaMaps::LuaTerrainDescription>(L, new LuaMaps::LuaTerrainDescription(descr));
 }
 
+/* RST
+   .. function:: save_campaign_data(campaign_name, scenario_name, text)
+
+      :arg campaign_name: the name of the current campaign, e.g. "empiretut" or "frisians"
+      :arg scenario_name: the name of the current scenario, e.g. "emp04" or "fri03"
+      :arg text: the text to write (use "\n" as line separator)
+
+      Saves a string that can be read by other scenarios.
+*/
+int LuaEditorGameBase::save_campaign_data(lua_State* L) {
+	const std::string campaign_name = luaL_checkstring(L, 2);
+	const std::string scenario_name = luaL_checkstring(L, 3);
+	std::string text = luaL_checkstring(L, 4);
+
+	std::string dir = kCampaignDataDir + g_fs->file_separator() + campaign_name;
+	boost::trim(dir);
+	g_fs->ensure_directory_exists(dir);
+
+	std::string complete_filename = dir + g_fs->file_separator() + scenario_name + kCampaignDataExtension;
+	boost::trim(complete_filename);
+
+	Profile profile;
+	Section& section = profile.create_section("campaign_data");
+
+	uint32_t line = 0;
+	while (!text.empty()) {
+		int32_t linebreak = text.find_first_of("\n");
+		std::string data;
+		if (linebreak < 0) {
+			data = text;
+			text = "";
+		}
+		else {
+			data = text.substr(0, linebreak);
+			text = text.substr(linebreak + 1);
+		}
+		std::string key = "line_" + std::to_string(line);
+		section.set_string(key.c_str(), data);
+		++line;
+	}
+	section.set_natural("size", line);
+	profile.write(complete_filename.c_str(), false);
+
+	return 0;
+}
+
+/* RST
+   .. function:: read_campaign_data(campaign_name, scenario_name)
+
+      :arg campaign_name: the name of the campaign, e.g. "empiretut" or "frisians"
+      :arg scenario_name: the name of the scenario that saved the data, e.g. "emp04" or "fri03"
+
+      Reads a string that was saved by another scenario. "\n" is used as line separator.
+      This function returns :const:`nil` if the file cannot be opened for reading.
+*/
+int LuaEditorGameBase::read_campaign_data(lua_State* L) {
+	const std::string campaign_name = luaL_checkstring(L, 2);
+	const std::string scenario_name = luaL_checkstring(L, 3);
+
+	std::string complete_filename = kCampaignDataDir + g_fs->file_separator() + campaign_name +
+			g_fs->file_separator() + scenario_name + kCampaignDataExtension;
+	boost::trim(complete_filename);
+
+	Profile profile;
+	profile.read(complete_filename.c_str());
+	Section* section = profile.get_section("campaign_data");
+	if (section == nullptr) {
+		lua_pushnil(L);
+	}
+	else {
+		uint32_t size = section->get_natural("size");
+		std::string text = "";
+		for(uint32_t i = 0; i < size; i++) {
+			if (i > 0) {
+				text += "\n";
+			}
+			std::string key = "line_" + std::to_string(i);
+			text += section->get_string(key.c_str());
+		}
+		lua_pushstring(L, text);
+	}
+
+	return 1;
+}
+
 /*
  ==========================================================
  C METHODS

=== modified file 'src/scripting/lua_bases.h'
--- src/scripting/lua_bases.h	2018-04-07 16:59:00 +0000
+++ src/scripting/lua_bases.h	2018-04-23 08:10:54 +0000
@@ -68,6 +68,8 @@
 	int get_worker_description(lua_State* L);
 	int get_resource_description(lua_State* L);
 	int get_terrain_description(lua_State* L);
+	int save_campaign_data(lua_State* L);
+	int read_campaign_data(lua_State* L);
 
 	/*
 	 * C methods


Follow ups