From 6739208bbe042ce7d6f1deb829e00ee71b2ca3e5 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Thu, 3 Dec 2015 23:02:02 +0100
Subject: [PATCH] allow passing arguments to lua scripts

---
 src/include/parameters.h    |  1 +
 src/include/script.h        |  1 +
 src/stratagus/script.cpp    | 30 ++++++++++++++++++++++++++----
 src/stratagus/stratagus.cpp | 10 +++++++---
 4 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/include/parameters.h b/src/include/parameters.h
index 8ae97d966..e6c404b78 100644
--- a/src/include/parameters.h
+++ b/src/include/parameters.h
@@ -46,6 +46,7 @@ public:
 	std::string applicationName;
 	std::string luaStartFilename;
 	std::string luaEditorStartFilename;
+	std::string luaScriptArguments;
 	std::string LocalPlayerName;        /// Name of local player
 private:
 	std::string userDirectory;          /// Directory containing user settings and data
diff --git a/src/include/script.h b/src/include/script.h
index ab133c9c0..a5890e65c 100644
--- a/src/include/script.h
+++ b/src/include/script.h
@@ -310,6 +310,7 @@ extern bool LuaToBoolean(lua_State *l, int index, int subIndex);
 
 extern void LuaGarbageCollect();  /// Perform garbage collection
 extern void InitLua();                /// Initialise Lua
+extern void LoadCcl(const std::string &filename, const std::string &luaArgStr);  /// Load ccl config file
 extern void LoadCcl(const std::string &filename);  /// Load ccl config file
 extern void SavePreferences();        /// Save user preferences
 extern int CclCommand(const std::string &command, bool exitOnError = true);
diff --git a/src/stratagus/script.cpp b/src/stratagus/script.cpp
index 5b7bd6ce1..91c22d5f6 100644
--- a/src/stratagus/script.cpp
+++ b/src/stratagus/script.cpp
@@ -205,10 +205,11 @@ static bool GetFileContent(const std::string &file, std::string &content)
 **  Load a file and execute it
 **
 **  @param file  File to load and execute
+**  @param nargs Number of arguments that caller has put on the stack
 **
 **  @return      0 for success, else exit.
 */
-int LuaLoadFile(const std::string &file)
+int LuaLoadFile(const std::string &file, const std::string &strArg)
 {
 	DebugPrint("Loading '%s'\n" _C_ file.c_str());
 
@@ -219,13 +220,30 @@ int LuaLoadFile(const std::string &file)
 	const int status = luaL_loadbuffer(Lua, content.c_str(), content.size(), file.c_str());
 
 	if (!status) {
-		LuaCall(0, 1);
+		if (!strArg.empty()) {
+			lua_pushstring(Lua, strArg.c_str());
+			LuaCall(1, 1);
+		} else {
+			LuaCall(0, 1);
+		}
 	} else {
 		report(status, true);
 	}
 	return status;
 }
 
+/**
+**  Load a file and execute it
+**
+**  @param file  File to load and execute
+**
+**  @return      0 for success, else exit.
+*/
+int LuaLoadFile(const std::string &file)
+{
+	return LuaLoadFile(file, std::string());
+}
+
 /**
 **  Save preferences
 **
@@ -2385,7 +2403,7 @@ void SavePreferences()
 /**
 **  Load stratagus config file.
 */
-void LoadCcl(const std::string &filename)
+void LoadCcl(const std::string &filename, const std::string &luaArgStr)
 {
 	//  Load and evaluate configuration file
 	CclInConfigFile = 1;
@@ -2396,11 +2414,15 @@ void LoadCcl(const std::string &filename)
 	}
 
 	ShowLoadProgress(_("Script %s\n"), name.c_str());
-	LuaLoadFile(name);
+	LuaLoadFile(name, luaArgStr);
 	CclInConfigFile = 0;
 	LuaGarbageCollect();
 }
 
+void LoadCcl(const std::string &filename)
+{
+	LoadCcl(filename, std::string());
+}
 
 void ScriptRegister()
 {
diff --git a/src/stratagus/stratagus.cpp b/src/stratagus/stratagus.cpp
index 72c44a9be..2cef6cb06 100644
--- a/src/stratagus/stratagus.cpp
+++ b/src/stratagus/stratagus.cpp
@@ -460,6 +460,7 @@ static void Usage()
 		"\t-e\t\tStart editor (instead of game)\n"
 		"\t-E file.lua\tEditor configuration start file (default editor.lua)\n"
 		"\t-F\t\tFull screen video mode\n"
+		"\t-G \"[options]\"\tGame options (passed to game scripts)\n"
 		"\t-h\t\tHelp shows this page\n"
 		"\t-i\t\tEnables unit info dumping into log (for debugging)\n"
 		"\t-I addr\t\tNetwork address to use\n"
@@ -533,7 +534,7 @@ static void RedirectOutput()
 void ParseCommandLine(int argc, char **argv, Parameters &parameters)
 {
 	for (;;) {
-		switch (getopt(argc, argv, "ac:d:D:eE:FhiI:lN:oOP:ps:S:u:v:Wx:Z?")) {
+		switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:Z?-")) {
 			case 'a':
 				EnableAssert = true;
 				continue;
@@ -561,6 +562,9 @@ void ParseCommandLine(int argc, char **argv, Parameters &parameters)
 				VideoForceFullScreen = 1;
 				Video.FullScreen = 1;
 				continue;
+			case 'G':
+				parameters.luaScriptArguments = optarg;
+				continue;
 			case 'i':
 				EnableUnitDebug = true;
 				continue;
@@ -661,7 +665,7 @@ void ParseCommandLine(int argc, char **argv, Parameters &parameters)
 	}
 
 	if (argc - optind > 1) {
-		fprintf(stderr, "too many files\n");
+		fprintf(stderr, "too many map files. if you meant to pass game arguments, these go after '--'\n");
 		Usage();
 		ExitFatal(-1);
 	}
@@ -754,7 +758,7 @@ int stratagusMain(int argc, char **argv)
 	// Initialise AI module
 	InitAiModule();
 
-	LoadCcl(parameters.luaStartFilename);
+	LoadCcl(parameters.luaStartFilename, parameters.luaScriptArguments);
 
 	PrintHeader();
 	PrintLicense();