public void Run(ModData modData, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; Console.WriteLine("This is an automatically generated listing of the new Lua map scripting API, generated for {0} of OpenRA.", Game.ModData.Manifest.Mod.Version); Console.WriteLine(); Console.WriteLine("OpenRA allows custom maps and missions to be scripted using Lua 5.1.\n" + "These scripts run in a sandbox that prevents access to unsafe functions (e.g. OS or file access), " + "and limits the memory and CPU usage of the scripts."); Console.WriteLine(); Console.WriteLine("You can access this interface by adding the [LuaScript](Traits#luascript) trait to the world actor in your map rules " + "(note, you must replace the spaces in the snippet below with a single tab for each level of indentation):"); Console.WriteLine("```\nRules:\n\tWorld:\n\t\tLuaScript:\n\t\t\tScripts: myscript.lua\n```"); Console.WriteLine(); Console.WriteLine("Map scripts can interact with the game engine in three ways:\n" + "* Global tables provide functions for interacting with the global world state, or performing general helper tasks.\n" + "They exist in the global namespace, and can be called directly using ```<table name>.<function name>```.\n" + "* Individual actors expose a collection of properties and commands that query information or modify their state.\n" + " * Some commands, marked as <em>queued activity</em>, are asynchronous. Activities are queued on the actor, and will run in " + "sequence until the queue is empty or the Stop command is called. Actors that are not performing an activity are Idle " + "(actor.IsIdle will return true). The properties and commands available on each actor depends on the traits that the actor " + "specifies in its rule definitions.\n" + "* Individual players expose a collection of properties and commands that query information or modify their state.\n" + "The properties and commands available on each actor depends on the traits that the actor specifies in its rule definitions.\n"); Console.WriteLine(); Console.WriteLine("For a basic guide about map scripts see the [`Map Scripting` wiki page](https://github.com/OpenRA/OpenRA/wiki/Map-scripting)."); Console.WriteLine(); var tables = Game.ModData.ObjectCreator.GetTypesImplementing <ScriptGlobal>() .OrderBy(t => t.Name); Console.WriteLine("<h3>Global Tables</h3>"); foreach (var t in tables) { var name = t.GetCustomAttributes <ScriptGlobalAttribute>(true).First().Name; var members = ScriptMemberWrapper.WrappableMembers(t); Console.WriteLine("<table align=\"center\" width=\"1024\"><tr><th colspan=\"2\" width=\"1024\">{0}</th></tr>", name); foreach (var m in members.OrderBy(m => m.Name)) { var desc = m.HasAttribute <DescAttribute>() ? m.GetCustomAttributes <DescAttribute>(true).First().Lines.JoinWith("\n") : ""; Console.WriteLine("<tr><td align=\"right\" width=\"50%\"><strong>{0}</strong></td><td>{1}</td></tr>".F(m.LuaDocString(), desc)); } Console.WriteLine("</table>"); } Console.WriteLine("<h3>Actor Properties / Commands</h3>"); var actorCategories = Game.ModData.ObjectCreator.GetTypesImplementing <ScriptActorProperties>().SelectMany(cg => { var catAttr = cg.GetCustomAttributes <ScriptPropertyGroupAttribute>(false).FirstOrDefault(); var category = catAttr != null ? catAttr.Category : "Unsorted"; var required = RequiredTraitNames(cg); return(ScriptMemberWrapper.WrappableMembers(cg).Select(mi => Tuple.Create(category, mi, required))); }).GroupBy(g => g.Item1).OrderBy(g => g.Key); foreach (var kv in actorCategories) { Console.WriteLine("<table align=\"center\" width=\"1024\"><tr><th colspan=\"2\" width=\"1024\">{0}</th></tr>", kv.Key); foreach (var property in kv.OrderBy(p => p.Item2.Name)) { var mi = property.Item2; var required = property.Item3; var hasDesc = mi.HasAttribute <DescAttribute>(); var hasRequires = required.Any(); var isActivity = mi.HasAttribute <ScriptActorPropertyActivityAttribute>(); Console.WriteLine("<tr><td width=\"50%\" align=\"right\"><strong>{0}</strong>", mi.LuaDocString()); if (isActivity) { Console.WriteLine("<br /><em>Queued Activity</em>"); } Console.WriteLine("</td><td>"); if (hasDesc) { Console.WriteLine(mi.GetCustomAttributes <DescAttribute>(false).First().Lines.JoinWith("\n")); } if (hasDesc && hasRequires) { Console.WriteLine("<br />"); } if (hasRequires) { Console.WriteLine("<b>Requires {1}:</b> {0}".F(required.JoinWith(", "), required.Length == 1 ? "Trait" : "Traits")); } Console.WriteLine("</td></tr>"); } Console.WriteLine("</table>"); } Console.WriteLine("<h3>Player Properties / Commands</h3>"); var playerCategories = Game.ModData.ObjectCreator.GetTypesImplementing <ScriptPlayerProperties>().SelectMany(cg => { var catAttr = cg.GetCustomAttributes <ScriptPropertyGroupAttribute>(false).FirstOrDefault(); var category = catAttr != null ? catAttr.Category : "Unsorted"; var required = RequiredTraitNames(cg); return(ScriptMemberWrapper.WrappableMembers(cg).Select(mi => Tuple.Create(category, mi, required))); }).GroupBy(g => g.Item1).OrderBy(g => g.Key); foreach (var kv in playerCategories) { Console.WriteLine("<table align=\"center\" width=\"1024\"><tr><th colspan=\"2\" width=\"1024\">{0}</th></tr>", kv.Key); foreach (var property in kv.OrderBy(p => p.Item2.Name)) { var mi = property.Item2; var required = property.Item3; var hasDesc = mi.HasAttribute <DescAttribute>(); var hasRequires = required.Any(); var isActivity = mi.HasAttribute <ScriptActorPropertyActivityAttribute>(); Console.WriteLine("<tr><td width=\"50%\" align=\"right\"><strong>{0}</strong>", mi.LuaDocString()); if (isActivity) { Console.WriteLine("<br /><em>Queued Activity</em>"); } Console.WriteLine("</td><td>"); if (hasDesc) { Console.WriteLine(mi.GetCustomAttributes <DescAttribute>(false).First().Lines.JoinWith("\n")); } if (hasDesc && hasRequires) { Console.WriteLine("<br />"); } if (hasRequires) { Console.WriteLine("<b>Requires {1}:</b> {0}".F(required.JoinWith(", "), required.Length == 1 ? "Trait" : "Traits")); } Console.WriteLine("</td></tr>"); } Console.WriteLine("</table>"); } }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = utility.ModData; Console.WriteLine("local interpreter = {"); Console.WriteLine(" name = \"OpenRA\","); Console.WriteLine(" description = \"OpenRA map scripting Lua API\","); Console.WriteLine(" api = {\"baselib\", \"openra\"},"); Console.WriteLine(" hasdebugger = false,"); Console.WriteLine(" skipcompile = true,"); Console.WriteLine("}"); Console.WriteLine(); Console.WriteLine("-- This is an automatically generated Lua API definition generated for {0} of OpenRA.", Game.ModData.Manifest.Metadata.Version); Console.WriteLine("-- https://github.com/OpenRA/OpenRA/wiki/Utility was used with the --zbstudio-lua-api parameter."); Console.WriteLine("-- See https://github.com/OpenRA/OpenRA/wiki/Lua-API for human readable documentation."); Console.WriteLine(); Console.WriteLine("local api = {"); var tables = Game.ModData.ObjectCreator.GetTypesImplementing <ScriptGlobal>().OrderBy(t => t.Name); foreach (var t in tables) { var name = t.GetCustomAttributes <ScriptGlobalAttribute>(true).First().Name; Console.WriteLine(" " + name + " = {"); Console.WriteLine(" type = \"class\","); Console.WriteLine(" childs = {"); var members = ScriptMemberWrapper.WrappableMembers(t); foreach (var member in members.OrderBy(m => m.Name)) { Console.WriteLine(" " + member.Name + " = {"); var methodInfo = member as MethodInfo; if (methodInfo != null) { Console.WriteLine(" type = \"function\","); } var propertyInfo = member as PropertyInfo; if (propertyInfo != null) { Console.WriteLine(" type = \"value\","); } if (member.HasAttribute <DescAttribute>()) { var desc = member.GetCustomAttributes <DescAttribute>(true).First().Lines.JoinWith("\n"); Console.WriteLine(" description = [[{0}]],", desc); } if (methodInfo != null) { var parameters = methodInfo.GetParameters().Select(pi => pi.LuaDocString()); Console.WriteLine(" args = \"({0})\",", parameters.JoinWith(", ")); var returnType = methodInfo.ReturnType.LuaDocString(); Console.WriteLine(" returns = \"({0})\",", returnType); } Console.WriteLine(" },"); } Console.WriteLine(" }"); Console.WriteLine(" },"); } var actorProperties = Game.ModData.ObjectCreator.GetTypesImplementing <ScriptActorProperties>().SelectMany(cg => { return(ScriptMemberWrapper.WrappableMembers(cg)); }); var scriptProperties = Game.ModData.ObjectCreator.GetTypesImplementing <ScriptPlayerProperties>().SelectMany(cg => { return(ScriptMemberWrapper.WrappableMembers(cg)); }); var properties = actorProperties.Concat(scriptProperties); foreach (var property in properties.OrderBy(m => m.Name)) { Console.WriteLine(" " + property.Name + " = {"); var methodInfo = property as MethodInfo; if (methodInfo != null) { Console.WriteLine(" type = \"function\","); } var propertyInfo = property as PropertyInfo; if (propertyInfo != null) { Console.WriteLine(" type = \"value\","); } if (property.HasAttribute <DescAttribute>()) { var desc = property.GetCustomAttributes <DescAttribute>(true).First().Lines.JoinWith("\n"); Console.WriteLine(" description = [[{0}]],", desc); } if (methodInfo != null) { var parameters = methodInfo.GetParameters().Select(pi => pi.LuaDocString()); Console.WriteLine(" args = \"({0})\",", parameters.JoinWith(", ")); var returnType = methodInfo.ReturnType.LuaDocString(); Console.WriteLine(" returns = \"({0})\",", returnType); } Console.WriteLine(" },"); } Console.WriteLine("}"); Console.WriteLine(); Console.WriteLine("return {"); Console.WriteLine(" name = \"OpenRA\","); Console.WriteLine(" description = \"Adds API description for auto-complete and tooltip support for OpenRA.\","); Console.WriteLine(" author = \"Matthias Mailänder\","); Console.WriteLine($" version = \"{Game.ModData.Manifest.Metadata.Version.Split('-').LastOrDefault()}\","); Console.WriteLine(); Console.WriteLine(" onRegister = function(self)"); Console.WriteLine(" ide:AddAPI(\"lua\", \"openra\", api)"); Console.WriteLine(" ide:AddInterpreter(\"openra\", interpreter)"); Console.WriteLine(" end,"); Console.WriteLine(); Console.WriteLine(" onUnRegister = function(self)"); Console.WriteLine(" ide:RemoveAPI(\"lua\", \"openra\")"); Console.WriteLine(" ide:RemoveInterpreter(\"openra\")"); Console.WriteLine(" end,"); Console.WriteLine("}"); }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. Game.ModData = utility.ModData; var version = utility.ModData.Manifest.Metadata.Version; if (args.Length > 1) { version = args[1]; } Console.WriteLine("This is an automatically generated listing of the Lua map scripting API for version {0} of OpenRA.", version); Console.WriteLine(); Console.WriteLine("OpenRA allows custom maps and missions to be scripted using Lua 5.1."); Console.WriteLine("These scripts run in a sandbox that prevents access to unsafe functions (e.g. OS or file access), " + "and limits the memory and CPU usage of the scripts."); Console.WriteLine(); Console.WriteLine("You can access this interface by adding the [LuaScript](../traits/#luascript) trait to the world actor in your map rules " + "(note, you must replace the spaces in the snippet below with a single tab for each level of indentation):"); Console.WriteLine("```\nRules:\n\tWorld:\n\t\tLuaScript:\n\t\t\tScripts: myscript.lua\n```"); Console.WriteLine(); Console.WriteLine("Map scripts can interact with the game engine in three ways:"); Console.WriteLine(); Console.WriteLine("* Global tables provide functions for interacting with the global world state, or performing general helper tasks."); Console.WriteLine("They exist in the global namespace, and can be called directly using ```<table name>.<function name>```."); Console.WriteLine("* Individual actors expose a collection of properties and commands that query information or modify their state."); Console.WriteLine(" * Some commands, marked as <em>queued activity</em>, are asynchronous. Activities are queued on the actor, and will run in " + "sequence until the queue is empty or the Stop command is called. Actors that are not performing an activity are Idle " + "(actor.IsIdle will return true). The properties and commands available on each actor depends on the traits that the actor " + "specifies in its rule definitions."); Console.WriteLine("* Individual players expose a collection of properties and commands that query information or modify their state."); Console.WriteLine("The properties and commands available on each actor depends on the traits that the actor specifies in its rule definitions."); Console.WriteLine(); Console.WriteLine("For a basic guide about map scripts see the [`Map Scripting` wiki page](https://github.com/OpenRA/OpenRA/wiki/Map-scripting)."); Console.WriteLine(); var tables = utility.ModData.ObjectCreator.GetTypesImplementing <ScriptGlobal>() .OrderBy(t => t.Name); Console.WriteLine("## Global Tables"); foreach (var t in tables) { var name = t.GetCustomAttributes <ScriptGlobalAttribute>(true).First().Name; var members = ScriptMemberWrapper.WrappableMembers(t); Console.WriteLine(); Console.WriteLine("### " + name); Console.WriteLine(); Console.WriteLine("| Function | Description |"); Console.WriteLine("|---------:|-------------|"); foreach (var m in members.OrderBy(m => m.Name)) { var desc = m.HasAttribute <DescAttribute>() ? m.GetCustomAttributes <DescAttribute>(true).First().Lines.JoinWith("<br />") : ""; Console.WriteLine($"| **{m.LuaDocString()}** | {desc} |"); } } Console.WriteLine(); Console.WriteLine("## Actor Properties / Commands"); var actorCategories = utility.ModData.ObjectCreator.GetTypesImplementing <ScriptActorProperties>().SelectMany(cg => { var catAttr = cg.GetCustomAttributes <ScriptPropertyGroupAttribute>(false).FirstOrDefault(); var category = catAttr != null ? catAttr.Category : "Unsorted"; var required = RequiredTraitNames(cg); return(ScriptMemberWrapper.WrappableMembers(cg).Select(mi => (category, mi, required))); }).GroupBy(g => g.Item1).OrderBy(g => g.Key); foreach (var kv in actorCategories) { Console.WriteLine(); Console.WriteLine("### " + kv.Key); Console.WriteLine(); Console.WriteLine("| Function | Description |"); Console.WriteLine("|---------:|-------------|"); foreach (var property in kv.OrderBy(p => p.Item2.Name)) { var mi = property.Item2; var required = property.Item3; var hasDesc = mi.HasAttribute <DescAttribute>(); var hasRequires = required.Any(); var isActivity = mi.HasAttribute <ScriptActorPropertyActivityAttribute>(); Console.Write($"| **{mi.LuaDocString()}**"); if (isActivity) { Console.Write("<br />*Queued Activity*"); } Console.Write(" | "); if (hasDesc) { Console.Write(mi.GetCustomAttributes <DescAttribute>(false).First().Lines.JoinWith("<br />")); } if (hasDesc && hasRequires) { Console.Write("<br />"); } if (hasRequires) { Console.Write($"**Requires {(required.Length == 1 ? "Trait" : "Traits")}:** {required.JoinWith(", ")}"); } Console.WriteLine(" |"); } } Console.WriteLine(); Console.WriteLine("## Player Properties / Commands"); var playerCategories = utility.ModData.ObjectCreator.GetTypesImplementing <ScriptPlayerProperties>().SelectMany(cg => { var catAttr = cg.GetCustomAttributes <ScriptPropertyGroupAttribute>(false).FirstOrDefault(); var category = catAttr != null ? catAttr.Category : "Unsorted"; var required = RequiredTraitNames(cg); return(ScriptMemberWrapper.WrappableMembers(cg).Select(mi => (category, mi, required))); }).GroupBy(g => g.Item1).OrderBy(g => g.Key); foreach (var kv in playerCategories) { Console.WriteLine(); Console.WriteLine("### " + kv.Key); Console.WriteLine(); Console.WriteLine("| Function | Description |"); Console.WriteLine("|---------:|-------------|"); foreach (var property in kv.OrderBy(p => p.Item2.Name)) { var mi = property.Item2; var required = property.Item3; var hasDesc = mi.HasAttribute <DescAttribute>(); var hasRequires = required.Any(); var isActivity = mi.HasAttribute <ScriptActorPropertyActivityAttribute>(); Console.Write($"| **{mi.LuaDocString()}**"); if (isActivity) { Console.Write("<br />*Queued Activity*"); } Console.Write(" | "); if (hasDesc) { Console.Write(mi.GetCustomAttributes <DescAttribute>(false).First().Lines.JoinWith("<br />")); } if (hasDesc && hasRequires) { Console.Write("<br />"); } if (hasRequires) { Console.Write($"**Requires {(required.Length == 1 ? "Trait" : "Traits")}:** {required.JoinWith(", ")}"); } Console.WriteLine(" |"); } Console.WriteLine(); } }