├── Dependencies ├── Moq.dll └── Ionic.Zip.Reduced.dll ├── QuestJSWeb ├── Views │ ├── _ViewStart.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ ├── Compile │ │ ├── Result.cshtml │ │ └── Index.cshtml │ └── Web.config ├── Global.asax ├── Scripts │ ├── _references.js │ ├── respond.min.js │ └── jquery.validate.unobtrusive.min.js ├── Settings.template.config ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── App_Start │ ├── FilterConfig.cs │ ├── RouteConfig.cs │ ├── WebApiConfig.cs │ ├── BundleConfig.cs │ └── Startup.Auth.cs ├── Startup.cs ├── Controllers │ ├── HomeController.cs │ └── CompileController.cs ├── Models │ └── CompileModel.cs ├── Global.asax.cs ├── Content │ └── Site.css ├── Web.Debug.config ├── Web.Release.config ├── Properties │ └── AssemblyInfo.cs ├── packages.config └── web.config ├── Compiler ├── images │ ├── quest.png │ ├── ta-logo.png │ ├── glyphicons-halflings.png │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_228ef1_256x240.png │ ├── ui-icons_ef8c08_256x240.png │ ├── ui-icons_ffd27a_256x240.png │ ├── ui-icons_ffffff_256x240.png │ ├── glyphicons-halflings-white.png │ ├── ui-bg_flat_10_000000_40x100.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png ├── packages.config ├── Scripts │ ├── FunctionCallParameters.cs │ ├── FinishScript.cs │ ├── DestroyScript.cs │ ├── ErrorScript.cs │ ├── InsertScript.cs │ ├── PictureScript.cs │ ├── DelegateImplementation.cs │ ├── SetFieldScript.cs │ ├── MsgScript.cs │ ├── WaitScript.cs │ ├── OnReadyScript.cs │ ├── GetInputScript.cs │ ├── ReturnScript.cs │ ├── Context.cs │ ├── MultiScript.cs │ ├── WhileScript.cs │ ├── UndoScript.cs │ ├── AskScript.cs │ ├── InvokeScript.cs │ ├── IScript.cs │ ├── DoScript.cs │ ├── PlaySoundScript.cs │ ├── ListAddScript.cs │ ├── ScriptConstructorBase.cs │ ├── ShowMenuScript.cs │ ├── JSScript.cs │ ├── DictionaryAddScript.cs │ ├── RunDelegateScript.cs │ ├── FirstTimeScript.cs │ ├── ForScript.cs │ ├── RequestScript.cs │ ├── ForEachScript.cs │ ├── FunctionCallScript.cs │ ├── IfScript.cs │ ├── SwitchScript.cs │ ├── SetScript.cs │ └── CreateScript.cs ├── js │ └── jjmenu.css ├── GameLoader │ ├── ElementNameMapper.cs │ └── PackageReader.cs ├── QuestDictionary.cs ├── GameSaver │ ├── FunctionSaver.cs │ ├── WalkthroughSaver.cs │ ├── GameSaver.cs │ ├── GameWriter.cs │ └── ElementSavers.cs ├── Properties │ └── AssemblyInfo.cs ├── QuestList.cs ├── ElementFactory.cs ├── style.css ├── Expression.cs └── Element.cs ├── QuestCompiler ├── Images │ └── q2_48x48c.ico ├── app.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ └── Resources.Designer.cs ├── App.xaml ├── App.xaml.cs ├── Settings.cs ├── MainWindow.xaml └── QuestCompiler.csproj ├── Utility ├── packages.config ├── Utility.cs ├── Strings.cs ├── Classes.cs ├── Registry.cs ├── Properties │ └── AssemblyInfo.cs ├── JSInterop.cs └── Utility.csproj ├── TraceAndTestImpact.testsettings ├── Local.testsettings ├── Prototypes └── Knockout │ ├── index.html │ └── game.js ├── QuestJS.vsmdi ├── README.md ├── CompilerTests ├── UtilityTests.cs ├── Properties │ └── AssemblyInfo.cs ├── ExpressionTests.cs └── CompilerTests.csproj ├── LICENSE └── .gitignore /Dependencies/Moq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Dependencies/Moq.dll -------------------------------------------------------------------------------- /QuestJSWeb/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /Compiler/images/quest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/quest.png -------------------------------------------------------------------------------- /Compiler/images/ta-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ta-logo.png -------------------------------------------------------------------------------- /Dependencies/Ionic.Zip.Reduced.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Dependencies/Ionic.Zip.Reduced.dll -------------------------------------------------------------------------------- /QuestCompiler/Images/q2_48x48c.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/QuestCompiler/Images/q2_48x48c.ico -------------------------------------------------------------------------------- /QuestJSWeb/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="QuestJSWeb.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /QuestJSWeb/Scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/QuestJSWeb/Scripts/_references.js -------------------------------------------------------------------------------- /Compiler/images/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/glyphicons-halflings.png -------------------------------------------------------------------------------- /Compiler/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /Compiler/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /Compiler/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /Compiler/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /Compiler/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /QuestJSWeb/Settings.template.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Compiler/images/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /QuestJSWeb/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/QuestJSWeb/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /QuestJSWeb/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/QuestJSWeb/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /QuestJSWeb/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/QuestJSWeb/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Compiler/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /Compiler/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textadventures/quest-js/HEAD/Compiler/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /Compiler/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Utility/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /QuestCompiler/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /QuestCompiler/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /QuestJSWeb/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | -------------------------------------------------------------------------------- /QuestCompiler/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /QuestJSWeb/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace QuestJSWeb 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /QuestJSWeb/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Owin; 2 | using Owin; 3 | 4 | [assembly: OwinStartupAttribute(typeof(QuestJSWeb.Startup))] 5 | namespace QuestJSWeb 6 | { 7 | public partial class Startup 8 | { 9 | public void Configuration(IAppBuilder app) 10 | { 11 | ConfigureAuth(app); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /QuestCompiler/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace QuestCompiler 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /QuestJSWeb/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace QuestJSWeb.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index() 12 | { 13 | return RedirectToAction("Index", "Compile"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /TraceAndTestImpact.testsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | These are test settings for Trace and Test Impact. 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Local.testsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | These are default test settings for a local test run. 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Prototypes/Knockout/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Knockout Binding Test 5 | 6 | 7 | 8 | 9 | 10 |
11 | Object count: 12 |
13 |
14 |
15 | 16 | -------------------------------------------------------------------------------- /QuestJS.vsmdi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /QuestJSWeb/Views/Compile/Result.cshtml: -------------------------------------------------------------------------------- 1 | @model QuestJSWeb.Models.CompileResult 2 | 3 | @{ 4 | ViewBag.Title = "Result"; 5 | } 6 | 7 |

Result

8 | 9 | @if (Model.Success) 10 | { 11 |

Created successfully.

12 | 13 |

Download: @Model.DownloadUrl

14 | } 15 | else 16 | { 17 |

Failed to compile.

18 | 19 | 25 | } -------------------------------------------------------------------------------- /Utility/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using System.IO; 7 | using System.Windows.Forms; 8 | 9 | namespace TextAdventures.Utility 10 | { 11 | public static class Utility 12 | { 13 | public static string RemoveFileColonPrefix(string path) 14 | { 15 | if (path.StartsWith(@"file:\")) path = path.Substring(6); 16 | if (path.StartsWith(@"file:")) path = path.Substring(5); 17 | return path; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Utility/Strings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Utility 7 | { 8 | public static class Strings 9 | { 10 | public static bool IsNumeric(string expression) 11 | { 12 | return Microsoft.VisualBasic.Information.IsNumeric(expression); 13 | } 14 | 15 | public static string CapFirst(string text) 16 | { 17 | if (string.IsNullOrEmpty(text)) return text; 18 | return text.Substring(0, 1).ToUpper() + text.Substring(1); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /QuestJSWeb/Models/CompileModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Web; 6 | 7 | namespace QuestJSWeb.Models 8 | { 9 | public class CompileModel 10 | { 11 | [Required] 12 | [Display(Name = "File to upload")] 13 | public HttpPostedFileBase File { get; set; } 14 | } 15 | 16 | public class CompileResult 17 | { 18 | public bool Success { get; set; } 19 | public IEnumerable Errors { get; set; } 20 | public string DownloadUrl { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QuestJS 2 | ======= 3 | 4 | **THIS PROJECT IS NO LONGER BEING DEVELOPED OR MAINTAINED!** 5 | 6 | QuestJS takes in a [Quest 5](https://github.com/textadventures/quest) .quest file 7 | and spits out a folder full of HTML, CSS and JS. It was used for turning Quest games into apps, as the output can be wrapped using tools like PhoneGap. 8 | 9 | The source is being kept online here for the moment for reference, but it is **no longer being developed or maintained**. 10 | 11 | Instead, [Quest 6](https://github.com/textadventures/quest/tree/v6) is under development, which will provide a native JavaScript runtime for all Quest games which can run on any platform. 12 | -------------------------------------------------------------------------------- /Compiler/Scripts/FunctionCallParameters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | // TO DO: Redundant class, should simply be a field in FunctionCallScript 9 | 10 | internal class FunctionCallParameters 11 | { 12 | private IList m_parameters; 13 | 14 | public FunctionCallParameters(IList parameters) 15 | { 16 | m_parameters = parameters; 17 | } 18 | 19 | public IList Parameters 20 | { 21 | get { return m_parameters; } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Compiler/js/jjmenu.css: -------------------------------------------------------------------------------- 1 | div.jjmenu 2 | { 3 | font-size:20px; 4 | position:absolute; 5 | background:#fffef0; 6 | border-bottom:2px solid gray; 7 | border-right:1px solid gray; 8 | padding:0px; 9 | } 10 | 11 | div.jj_menu_item { 12 | color:black; 13 | border:1px solid gray; 14 | border-bottom:none; 15 | background: white; 16 | cursor:pointer; 17 | } 18 | 19 | div.jj_menu_item span { 20 | display:block; 21 | padding:4px; 22 | } 23 | 24 | div.jj_menu_item_more span { 25 | background:url(more.gif) right no-repeat; 26 | } 27 | div.jj_menu_item_more span { 28 | padding-right:20px; 29 | } 30 | 31 | div.jj_menu_item_hover { 32 | background:#e4e4e4; 33 | 34 | } -------------------------------------------------------------------------------- /Utility/Classes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | 7 | namespace TextAdventures.Utility 8 | { 9 | public static class Classes 10 | { 11 | public static bool IsConcrete(Type t) 12 | { 13 | return !t.IsAbstract && !t.IsGenericTypeDefinition && !t.IsInterface; 14 | } 15 | 16 | public static IEnumerable GetImplementations(Assembly assembly, Type interfaceType) 17 | { 18 | return assembly.GetTypes() 19 | .Where(p => interfaceType.IsAssignableFrom(p)) 20 | .Where(p => IsConcrete(p)); 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /QuestJSWeb/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace QuestJSWeb 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /QuestJSWeb/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Http; 5 | 6 | namespace QuestJSWeb 7 | { 8 | public static class WebApiConfig 9 | { 10 | public static void Register(HttpConfiguration config) 11 | { 12 | // Web API configuration and services 13 | 14 | // Web API routes 15 | config.MapHttpAttributeRoutes(); 16 | 17 | config.Routes.MapHttpRoute( 18 | name: "DefaultApi", 19 | routeTemplate: "api/{controller}/{id}", 20 | defaults: new { id = RouteParameter.Optional } 21 | ); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /QuestJSWeb/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Mvc; 7 | using System.Web.Optimization; 8 | using System.Web.Routing; 9 | 10 | namespace QuestJSWeb 11 | { 12 | public class MvcApplication : System.Web.HttpApplication 13 | { 14 | protected void Application_Start() 15 | { 16 | AreaRegistration.RegisterAllAreas(); 17 | GlobalConfiguration.Configure(WebApiConfig.Register); 18 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 19 | RouteConfig.RegisterRoutes(RouteTable.Routes); 20 | BundleConfig.RegisterBundles(BundleTable.Bundles); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Compiler/GameLoader/ElementNameMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | public class ElementNameMapper 9 | { 10 | private const string k_namePrefix = "_obj"; 11 | private Dictionary m_map = new Dictionary(); 12 | private int m_count = 0; 13 | 14 | public string AddToMap(string elementName) 15 | { 16 | m_count++; 17 | string mappedName = k_namePrefix + m_count; 18 | m_map.Add(elementName, mappedName); 19 | return mappedName; 20 | } 21 | 22 | public string GetMappedName(string elementName) 23 | { 24 | return m_map[elementName]; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CompilerTests/UtilityTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | using TextAdventures.Quest; 7 | 8 | namespace CompilerTests 9 | { 10 | [TestClass] 11 | public class UtilityTests 12 | { 13 | [TestMethod] 14 | public void TestConvertObjectDotNotation() 15 | { 16 | List objectNames = new List { "myobject", "otherobject" }; 17 | //Assert.AreEqual("test.attribute", Utility.ConvertObjectDotNotation("test.attribute", objectNames)); 18 | //Assert.AreEqual("object_myobject.attribute", Utility.ConvertObjectDotNotation("myobject.attribute", objectNames)); 19 | //Assert.AreEqual("object_otherobject.attribute", Utility.ConvertObjectDotNotation("otherobject.attribute", objectNames)); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /QuestJSWeb/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Set width on the form input elements since they're 100% wide by default */ 13 | input, 14 | select, 15 | textarea { 16 | max-width: 280px; 17 | } 18 | 19 | /* styles for validation helpers */ 20 | .field-validation-error { 21 | color: #b94a48; 22 | } 23 | 24 | .field-validation-valid { 25 | display: none; 26 | } 27 | 28 | input.input-validation-error { 29 | border: 1px solid #b94a48; 30 | } 31 | 32 | input[type="checkbox"].input-validation-error { 33 | border: 0 none; 34 | } 35 | 36 | .validation-summary-errors { 37 | color: #b94a48; 38 | } 39 | 40 | .validation-summary-valid { 41 | display: none; 42 | } -------------------------------------------------------------------------------- /Compiler/Scripts/FinishScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class FinishScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "finish"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new FinishScript(); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 0 }; } 23 | } 24 | } 25 | 26 | public class FinishScript : ScriptBase 27 | { 28 | public FinishScript() 29 | { 30 | } 31 | 32 | public override string Save(Context c) 33 | { 34 | return "finish();"; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Compiler/QuestDictionary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | public class QuestDictionary 9 | { 10 | public QuestDictionary() 11 | { 12 | } 13 | 14 | public QuestDictionary(IDictionary dictionary) 15 | { 16 | if (dictionary != null) 17 | { 18 | foreach (var kvp in dictionary) 19 | { 20 | m_dictionary.Add(kvp.Key, kvp.Value); 21 | } 22 | } 23 | } 24 | 25 | private Dictionary m_dictionary = new Dictionary(); 26 | 27 | public void Add(string key, T value) 28 | { 29 | m_dictionary.Add(key, value); 30 | } 31 | 32 | public Dictionary Dictionary { get { return m_dictionary; } } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /QuestJSWeb/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @ViewBag.Title - QuestJS 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 11 | 12 | 19 |
20 | @RenderBody() 21 |
22 |
23 |

© @DateTime.Now.Year textadventures.co.uk

24 |
25 |
26 | 27 | @Scripts.Render("~/bundles/jquery") 28 | @Scripts.Render("~/bundles/bootstrap") 29 | @RenderSection("scripts", required: false) 30 | 31 | 32 | -------------------------------------------------------------------------------- /Compiler/GameSaver/FunctionSaver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | internal class FunctionSaver : IElementSaver 9 | { 10 | public ElementType AppliesTo 11 | { 12 | get { return ElementType.Function; } 13 | } 14 | 15 | public void Save(Element e, GameWriter writer) 16 | { 17 | string paramNames = string.Join(", ", e.Fields[FieldDefinitions.ParamNames]); 18 | paramNames = Utility.ReplaceReservedVariableNames(paramNames); 19 | writer.AddLine("function " + e.Name.Replace(" ", Utility.SpaceReplacementString) + "(" + paramNames + ")"); 20 | writer.AddLine("{"); 21 | var context = new Context(); 22 | context.AddLocalVariable(e.Fields[FieldDefinitions.ParamNames].ToArray()); 23 | writer.AddLine(e.Fields[FieldDefinitions.Script].Save(context)); 24 | writer.AddLine("}"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Compiler/Scripts/DestroyScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class DestroyScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "destroy"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new DestroyScript(new Expression(parameters[0], GameLoader)); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 1 }; } 23 | } 24 | } 25 | 26 | public class DestroyScript : ScriptBase 27 | { 28 | private IFunction m_expr; 29 | 30 | public DestroyScript(IFunction expr) 31 | { 32 | m_expr = expr; 33 | } 34 | 35 | public override string Save(Context c) 36 | { 37 | return SaveScript("destroy", m_expr.Save(c)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Compiler/Scripts/ErrorScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class ErrorScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "error"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new ErrorScript(new Expression(parameters[0], GameLoader)); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 1 }; } 23 | } 24 | } 25 | 26 | public class ErrorScript : ScriptBase 27 | { 28 | private IFunction m_function; 29 | 30 | public ErrorScript(IFunction function) 31 | { 32 | m_function = function; 33 | } 34 | 35 | public override string Save(Context c) 36 | { 37 | return SaveScript("error", m_function.Save(c)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Compiler/Scripts/InsertScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class InsertScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "insert"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new InsertScript(new Expression(parameters[0], GameLoader)); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 1 }; } 23 | } 24 | } 25 | 26 | public class InsertScript : ScriptBase 27 | { 28 | private IFunction m_filename; 29 | 30 | public InsertScript(IFunction filename) 31 | { 32 | m_filename = filename; 33 | } 34 | 35 | public override string Save(Context c) 36 | { 37 | return SaveScript("insertHtml", m_filename.Save(c)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Compiler/Scripts/PictureScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class PictureScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "picture"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new PictureScript(new Expression(parameters[0], GameLoader)); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 1 }; } 23 | } 24 | } 25 | 26 | public class PictureScript : ScriptBase 27 | { 28 | private IFunction m_filename; 29 | 30 | public PictureScript(IFunction function) 31 | { 32 | m_filename = function; 33 | } 34 | 35 | public override string Save(Context c) 36 | { 37 | return SaveScript("picture", m_filename.Save(c)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Compiler/Scripts/DelegateImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | class DelegateImplementation 9 | { 10 | private Element m_delegateDef; 11 | private Element m_implementation; 12 | private string m_typeName; 13 | 14 | public DelegateImplementation(string typeName, Element def, Element impl) 15 | { 16 | m_delegateDef = def; 17 | m_implementation = impl; 18 | m_typeName = typeName; 19 | } 20 | 21 | public Element Definition 22 | { 23 | get { return m_delegateDef; } 24 | } 25 | 26 | public Element Implementation 27 | { 28 | get { return m_implementation; } 29 | } 30 | 31 | public string TypeName 32 | { 33 | get { return m_typeName; } 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return m_implementation.Fields[FieldDefinitions.Script].ToString(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Alex Warren 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Compiler/GameLoader/PackageReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using Ionic.Zip; 7 | 8 | namespace TextAdventures.Quest 9 | { 10 | internal class PackageReader 11 | { 12 | public class ReadResult 13 | { 14 | public string GameFile; 15 | public string Folder; 16 | } 17 | 18 | public ReadResult LoadPackage(string filename) 19 | { 20 | ReadResult result = new ReadResult(); 21 | string tempDir = Path.Combine(Path.GetTempPath(), "Quest", Guid.NewGuid().ToString(), Path.GetFileNameWithoutExtension(filename)); 22 | Directory.CreateDirectory(tempDir); 23 | ZipFile zip = ZipFile.Read(filename); 24 | zip.ExtractAll(tempDir); 25 | 26 | result.Folder = tempDir; 27 | result.GameFile = Path.Combine(tempDir, "game.aslx"); 28 | 29 | if (!File.Exists(result.GameFile)) 30 | { 31 | throw new InvalidDataException("Invalid game file"); 32 | } 33 | 34 | return result; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /QuestCompiler/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace QuestCompiler.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Utility/Registry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Microsoft.Win32; 6 | 7 | namespace TextAdventures.Utility 8 | { 9 | public static class Registry 10 | { 11 | public static object GetSetting(string product, string keyName, string valueName, object defaultValue) 12 | { 13 | return GetKey(product, keyName).GetValue(valueName, defaultValue); 14 | } 15 | 16 | public static void SaveSetting(string product, string keyName, string valueName, object value) 17 | { 18 | GetKey(product, keyName).SetValue(valueName, value); 19 | } 20 | 21 | private static RegistryKey GetKey(string product, string keyName) 22 | { 23 | return Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\" + product + @"\" + keyName); 24 | } 25 | 26 | public static object GetHKLMSetting(string product, string keyName, string valueName, object defaultValue) 27 | { 28 | RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"Software\" + product + @"\" + keyName); 29 | if (key == null) return defaultValue; 30 | return key.GetValue(valueName, defaultValue); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /QuestCompiler/Settings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Xml.Serialization; 7 | 8 | namespace QuestCompiler 9 | { 10 | public class Settings 11 | { 12 | public string Source { get; set; } 13 | public string Destination { get; set; } 14 | public string Profile { get; set; } 15 | public bool Debug { get; set; } 16 | public bool Minify { get; set; } 17 | public bool Gamebook { get; set; } 18 | } 19 | 20 | internal class SettingsManager 21 | { 22 | public Settings LoadSettings(string file) 23 | { 24 | XmlSerializer serializer = new XmlSerializer(typeof(Settings)); 25 | using (var stream = new FileStream(file, FileMode.Open)) 26 | { 27 | return (Settings)serializer.Deserialize(stream); 28 | } 29 | } 30 | 31 | public void SaveSettings(string file, Settings settings) 32 | { 33 | XmlSerializer serializer = new XmlSerializer(typeof(Settings)); 34 | using (var stream = new FileStream(file, FileMode.Create)) 35 | { 36 | serializer.Serialize(stream, settings); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /QuestJSWeb/Views/Compile/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model QuestJSWeb.Models.CompileModel 2 | 3 | @{ 4 | ViewBag.Title = "Compile"; 5 | } 6 | 7 |

Compile

8 | 9 |

This is the web version of QuestJS - a service for converting games written using Quest 10 | into HTML and JavaScript.

11 | 12 |

Upload your .quest file here, and after a few seconds you'll be able to download a zip file containing all the HTML, CSS and JavaScript required to run your game.

13 | 14 |

To generate your .quest file:

15 | 16 |
    17 |
  • If you're using the Windows desktop version of Quest, open your game in the editor, then click Tools, Publish.
  • 18 |
  • If you're using the web version of Quest, publish your game to textadventures.co.uk (you can keep it unlisted so it doesn't become public). Then from your game 19 | listing page, click the "Download file" link in the column on the right.
  • 20 |
21 | 22 |
23 | 24 | @Html.ValidationMessageFor(m => m.File) 25 | 26 |
27 | 28 |
-------------------------------------------------------------------------------- /Prototypes/Knockout/game.js: -------------------------------------------------------------------------------- 1 | function GameModel() { 2 | var self = this; 3 | self.objects = ko.observableArray(); 4 | 5 | self.objectCount = ko.computed(function(){ 6 | return self.objects().length; 7 | }); 8 | } 9 | 10 | function GameObject(name) { 11 | var self = this; 12 | self.name = name; 13 | self.attributes = ko.observableArray(); 14 | 15 | self.set = function(attribute, value) { 16 | if (!self.hasOwnProperty(attribute)) { 17 | self.attributes.push(attribute); 18 | self[attribute] = ko.observable(value); 19 | console.log("Added new attribute: " + self.name + "." + attribute + "=" + value); 20 | } 21 | else { 22 | self[attribute](value); 23 | console.log("Updated attribute: " + self.name + "." + attribute + "=" + value); 24 | } 25 | } 26 | } 27 | 28 | $(function(){ 29 | var game = new GameModel(); 30 | var book = new GameObject("book"); 31 | game.objects.push(book); 32 | book.set("look", "Initial look description"); 33 | book.set("look", "Updated look description"); 34 | book.set("take", function(){ 35 | console.log ("Ran initial take function"); 36 | }); 37 | book.set("take", function(){ 38 | console.log ("Ran updated take function"); 39 | }); 40 | ko.applyBindings(game); 41 | 42 | $("#game-content").html("Initialised. Book description is '" + book.look() + "'"); 43 | book.take()(); 44 | }); -------------------------------------------------------------------------------- /Compiler/Scripts/SetFieldScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class SetFieldScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "set"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new SetFieldScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader)); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 3 }; } 23 | } 24 | } 25 | 26 | public class SetFieldScript : ScriptBase 27 | { 28 | private IFunction m_obj; 29 | private IFunction m_field; 30 | private IFunction m_value; 31 | 32 | public SetFieldScript(IFunction obj, IFunction field, IFunction value) 33 | { 34 | m_obj = obj; 35 | m_field = field; 36 | m_value = value; 37 | } 38 | 39 | public override string Save(Context c) 40 | { 41 | return SaveScript("set", m_obj.Save(c), m_field.Save(c), m_value.Save(c)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Compiler/Scripts/MsgScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class MsgScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "msg"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | if (GameLoader.Version >= WorldModelVersion.v540) 18 | { 19 | return new FunctionCallScript(GameLoader, "OutputText", 20 | new List { new Expression(parameters[0], GameLoader) }, null); 21 | } 22 | return new MsgScript(new Expression(parameters[0], GameLoader)); 23 | } 24 | 25 | protected override int[] ExpectedParameters 26 | { 27 | get { return new int[] { 1 }; } 28 | } 29 | } 30 | 31 | public class MsgScript : ScriptBase 32 | { 33 | private IFunction m_function; 34 | 35 | public MsgScript(IFunction function) 36 | { 37 | m_function = function; 38 | } 39 | 40 | public override string Save(Context c) 41 | { 42 | return SaveScript("msg", m_function.Save(c)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /QuestJSWeb/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /QuestJSWeb/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace QuestJSWeb 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js", 24 | "~/Scripts/respond.js")); 25 | 26 | bundles.Add(new StyleBundle("~/Content/css").Include( 27 | "~/Content/bootstrap.css", 28 | "~/Content/site.css")); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Compiler/Scripts/WaitScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class WaitScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "wait"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string callback = Utility.GetScript(script.Substring(4).Trim()); 18 | IScript callbackScript = ScriptFactory.CreateScript(callback); 19 | return new WaitScript(ScriptFactory, callbackScript); 20 | } 21 | 22 | public IScriptFactory ScriptFactory { get; set; } 23 | public GameLoader GameLoader { get; set; } 24 | } 25 | 26 | public class WaitScript : ScriptBase 27 | { 28 | private IScript m_callbackScript; 29 | private IScriptFactory m_scriptFactory; 30 | 31 | public WaitScript(IScriptFactory scriptFactory, IScript callbackScript) 32 | { 33 | m_scriptFactory = scriptFactory; 34 | m_callbackScript = callbackScript; 35 | } 36 | 37 | public override string Save(Context c) 38 | { 39 | return string.Format("wait_async (function() {{ {0} }});", 40 | m_callbackScript.Save(c) 41 | ); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Compiler/Scripts/OnReadyScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class OnReadyScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "on ready"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string callback = Utility.GetScript(script.Substring(8).Trim()); 18 | IScript callbackScript = ScriptFactory.CreateScript(callback); 19 | return new OnReadyScript(ScriptFactory, callbackScript); 20 | } 21 | 22 | public IScriptFactory ScriptFactory { get; set; } 23 | public GameLoader GameLoader { get; set; } 24 | } 25 | 26 | public class OnReadyScript : ScriptBase 27 | { 28 | private IScript m_callbackScript; 29 | private IScriptFactory m_scriptFactory; 30 | 31 | public OnReadyScript(IScriptFactory scriptFactory, IScript callbackScript) 32 | { 33 | m_scriptFactory = scriptFactory; 34 | m_callbackScript = callbackScript; 35 | } 36 | 37 | public override string Save(Context c) 38 | { 39 | return string.Format("on_ready (function() {{ {0} }});", 40 | m_callbackScript.Save(c) 41 | ); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Compiler/Scripts/GetInputScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class GetInputScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "get input"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string callback = Utility.GetScript(script.Substring(9).Trim()); 18 | IScript callbackScript = ScriptFactory.CreateScript(callback); 19 | return new GetInputScript(ScriptFactory, callbackScript); 20 | } 21 | 22 | public IScriptFactory ScriptFactory { get; set; } 23 | public GameLoader GameLoader { get; set; } 24 | } 25 | 26 | public class GetInputScript : ScriptBase 27 | { 28 | private IScript m_callbackScript; 29 | private IScriptFactory m_scriptFactory; 30 | 31 | public GetInputScript(IScriptFactory scriptFactory, IScript callbackScript) 32 | { 33 | m_scriptFactory = scriptFactory; 34 | m_callbackScript = callbackScript; 35 | } 36 | 37 | public override string Save(Context c) 38 | { 39 | return string.Format("getinput_async (function(result) {{ {0} }});", 40 | m_callbackScript.Save(c) 41 | ); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /QuestJSWeb/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Compiler/Scripts/ReturnScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class ReturnScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "return"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | throw new Exception("Invalid constructor for 'return' script"); 18 | } 19 | 20 | protected override IScript CreateInt(List parameters, Element proc) 21 | { 22 | return new ReturnScript(new Expression(parameters[0], GameLoader)); 23 | } 24 | 25 | protected override int[] ExpectedParameters 26 | { 27 | get { return new int[] { 1 }; } 28 | } 29 | 30 | protected override bool RequireProcedure 31 | { 32 | get 33 | { 34 | return true; 35 | } 36 | } 37 | } 38 | 39 | public class ReturnScript : ScriptBase 40 | { 41 | private IFunction m_returnValue; 42 | 43 | public ReturnScript(IFunction returnValue) 44 | { 45 | m_returnValue = returnValue; 46 | } 47 | 48 | public override string Save(Context c) 49 | { 50 | return SaveScript("return", m_returnValue.Save(c)); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Compiler/Scripts/Context.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using System.Collections.Generic; 3 | //using System.Linq; 4 | //using System.Text; 5 | //using System.Collections; 6 | 7 | //namespace TextAdventures.Quest.Scripts 8 | //{ 9 | // public class NoReturnValue 10 | // { 11 | // } 12 | 13 | // public class Context 14 | // { 15 | // private Parameters m_parameters; 16 | // private object m_returnValue = new NoReturnValue(); 17 | 18 | // public Context() 19 | // { 20 | // } 21 | 22 | // public Parameters Parameters 23 | // { 24 | // set { m_parameters = value; } 25 | // get { return m_parameters; } 26 | // } 27 | 28 | // public object ReturnValue 29 | // { 30 | // get { return m_returnValue; } 31 | // set { m_returnValue = value; } 32 | // } 33 | // } 34 | 35 | // public class Parameters : Dictionary 36 | // { 37 | // public Parameters() 38 | // { 39 | // } 40 | 41 | // public Parameters(string key, object value) 42 | // { 43 | // Add(key, value); 44 | // } 45 | 46 | // public Parameters(IDictionary parameters) 47 | // { 48 | // foreach (object key in parameters.Keys) 49 | // { 50 | // if (key is string) 51 | // { 52 | // Add((string)key, parameters[key]); 53 | // } 54 | // } 55 | // } 56 | // } 57 | //} 58 | -------------------------------------------------------------------------------- /Utility/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Utility")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Utility")] 13 | [assembly: AssemblyCopyright("Copyright © 2013 Text Adventures Ltd")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1a6e6b6f-6bf2-4f9e-8e93-57b344d9b5cc")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("5.5.*")] 36 | 37 | -------------------------------------------------------------------------------- /Compiler/GameSaver/WalkthroughSaver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | internal class WalkthroughSaver : ElementSaverBase, IElementSaver 9 | { 10 | public ElementType AppliesTo 11 | { 12 | get { return ElementType.Walkthrough; } 13 | } 14 | 15 | public void Save(Element e, GameWriter writer) 16 | { 17 | base.SaveElementFields(e.Name, e, writer); 18 | } 19 | 20 | protected override object ConvertField(Element e, string fieldName, object value) 21 | { 22 | if (fieldName == "steps") 23 | { 24 | QuestList steps = (QuestList)value; 25 | QuestList result = new QuestList(); 26 | 27 | foreach (string step in steps) 28 | { 29 | if (step.StartsWith("assert:")) 30 | { 31 | string expr = step.Substring(7); 32 | Expression expression = new Expression(expr, e.Loader); 33 | result.Add("assert:" + expression.Save(new Context())); 34 | } 35 | else 36 | { 37 | result.Add(step); 38 | } 39 | } 40 | return result; 41 | } 42 | return value; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /CompilerTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CompilerTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("CompilerTests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0a9fb6f9-42f4-4eb3-b5ba-85371fc60f34")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Compiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Quest Compiler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Text Adventures Ltd")] 12 | [assembly: AssemblyProduct("Quest Compiler")] 13 | [assembly: AssemblyCopyright("Copyright © 2013 Text Adventures Ltd")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("755cb553-c53e-4ee5-ac5d-0bff0843e316")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("6.0.*")] -------------------------------------------------------------------------------- /QuestJSWeb/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("QuestJSWeb")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("QuestJSWeb")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("eb26ae17-aaf4-416d-bce6-ab1e55bb7646")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /QuestJSWeb/App_Start/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity; 2 | using Microsoft.Owin; 3 | using Microsoft.Owin.Security.Cookies; 4 | using Owin; 5 | 6 | namespace QuestJSWeb 7 | { 8 | public partial class Startup 9 | { 10 | // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 11 | public void ConfigureAuth(IAppBuilder app) 12 | { 13 | // Enable the application to use a cookie to store information for the signed in user 14 | app.UseCookieAuthentication(new CookieAuthenticationOptions 15 | { 16 | AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 17 | LoginPath = new PathString("/Account/Login") 18 | }); 19 | // Use a cookie to temporarily store information about a user logging in with a third party login provider 20 | app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 21 | 22 | // Uncomment the following lines to enable logging in with third party login providers 23 | //app.UseMicrosoftAccountAuthentication( 24 | // clientId: "", 25 | // clientSecret: ""); 26 | 27 | //app.UseTwitterAuthentication( 28 | // consumerKey: "", 29 | // consumerSecret: ""); 30 | 31 | //app.UseFacebookAuthentication( 32 | // appId: "", 33 | // appSecret: ""); 34 | 35 | //app.UseGoogleAuthentication(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Compiler/Scripts/MultiScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class MultiScript : ScriptBase 9 | { 10 | private List m_scripts; 11 | 12 | public MultiScript(params IScript[] scripts) 13 | { 14 | m_scripts = new List(scripts); 15 | } 16 | 17 | private MultiScript() { } 18 | 19 | public void Add(params IScript[] scripts) 20 | { 21 | m_scripts.AddRange(scripts); 22 | } 23 | 24 | public IEnumerable Scripts 25 | { 26 | get 27 | { 28 | return m_scripts.AsReadOnly(); 29 | } 30 | } 31 | 32 | public override string Line 33 | { 34 | get 35 | { 36 | string result = string.Empty; 37 | foreach (IScript script in m_scripts) 38 | { 39 | result += script.Line + Environment.NewLine; 40 | } 41 | return result; 42 | } 43 | set 44 | { 45 | throw new Exception("Cannot set Line in MultiScript"); 46 | } 47 | } 48 | 49 | public override string Save(Context c) 50 | { 51 | string result = string.Empty; 52 | 53 | foreach (IScript script in m_scripts) 54 | { 55 | if (result.Length > 0) result += Environment.NewLine; 56 | result += script.Save(c); 57 | } 58 | 59 | return result; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Compiler/Scripts/WhileScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class WhileScriptConstructor : IScriptConstructor 10 | { 11 | public string Keyword 12 | { 13 | get { return "while"; } 14 | } 15 | 16 | public IScript Create(string script, Element proc) 17 | { 18 | string afterExpr; 19 | string param = Utility.GetParameter(script, out afterExpr); 20 | string loop = Utility.GetScript(afterExpr); 21 | IScript loopScript = ScriptFactory.CreateScript(loop); 22 | 23 | return new WhileScript(new Expression(param, GameLoader), loopScript); 24 | } 25 | 26 | public IScriptFactory ScriptFactory { get; set; } 27 | 28 | public GameLoader GameLoader { get; set; } 29 | } 30 | 31 | public class WhileScript : ScriptBase 32 | { 33 | private IFunction m_expression; 34 | private IScript m_loopScript; 35 | 36 | public WhileScript(IFunction expression, IScript loopScript) 37 | { 38 | m_expression = expression; 39 | m_loopScript = loopScript; 40 | } 41 | 42 | public override string Save(Context c) 43 | { 44 | string result = string.Format("while ({0}) {{\n", m_expression.Save(c)); 45 | result += m_loopScript.Save(c); 46 | result += Environment.NewLine + "}"; 47 | return result; 48 | } 49 | 50 | public override string Keyword 51 | { 52 | get 53 | { 54 | return "while"; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /QuestJSWeb/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Compiler/Scripts/UndoScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class UndoScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "undo"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new UndoScript(); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 0 }; } 23 | } 24 | } 25 | 26 | public class UndoScript : ScriptBase 27 | { 28 | public UndoScript() 29 | { 30 | } 31 | 32 | public override string Save(Context c) 33 | { 34 | return "undo();"; 35 | } 36 | } 37 | 38 | public class StartTransactionConstructor : ScriptConstructorBase 39 | { 40 | public override string Keyword 41 | { 42 | get { return "start transaction"; } 43 | } 44 | 45 | protected override IScript CreateInt(List parameters) 46 | { 47 | return new StartTransactionScript(new Expression(parameters[0], GameLoader)); 48 | } 49 | 50 | protected override int[] ExpectedParameters 51 | { 52 | get { return new int[] { 1 }; } 53 | } 54 | } 55 | 56 | public class StartTransactionScript : ScriptBase 57 | { 58 | private IFunction m_command; 59 | 60 | public StartTransactionScript(IFunction command) 61 | { 62 | m_command = command; 63 | } 64 | 65 | public override string Save(Context c) 66 | { 67 | return SaveScript("starttransaction", m_command.Save(c)); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Compiler/Scripts/AskScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class AskScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "ask"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string afterExpr; 18 | string param = Utility.GetParameter(script, out afterExpr); 19 | string callback = Utility.GetScript(afterExpr); 20 | 21 | string[] parameters = Utility.SplitParameter(param).ToArray(); 22 | if (parameters.Count() != 1) 23 | { 24 | throw new Exception(string.Format("'ask' script should have 1 parameter: 'ask ({0})'", param)); 25 | } 26 | IScript callbackScript = ScriptFactory.CreateScript(callback); 27 | 28 | return new AskScript(ScriptFactory, new Expression(parameters[0], GameLoader), callbackScript); 29 | } 30 | 31 | public IScriptFactory ScriptFactory { get; set; } 32 | 33 | public GameLoader GameLoader { get; set; } 34 | } 35 | 36 | public class AskScript : ScriptBase 37 | { 38 | private IFunction m_caption; 39 | private IScript m_callbackScript; 40 | private IScriptFactory m_scriptFactory; 41 | 42 | public AskScript(IScriptFactory scriptFactory, IFunction caption, IScript callbackScript) 43 | { 44 | m_scriptFactory = scriptFactory; 45 | m_caption = caption; 46 | m_callbackScript = callbackScript; 47 | } 48 | 49 | public override string Save(Context c) 50 | { 51 | return string.Format("ask ({0}, function(result) {{ {1} }});", 52 | m_caption.Save(c), 53 | m_callbackScript.Save(c) 54 | ); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Compiler/Scripts/InvokeScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class InvokeScriptConstructor : ScriptConstructorBase 10 | { 11 | public override string Keyword 12 | { 13 | get { return "invoke"; } 14 | } 15 | 16 | protected override IScript CreateInt(List parameters) 17 | { 18 | switch (parameters.Count) 19 | { 20 | case 1: 21 | return new InvokeScript(new Expression(parameters[0], GameLoader)); 22 | case 2: 23 | return new InvokeScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader)); 24 | } 25 | return null; 26 | } 27 | 28 | protected override int[] ExpectedParameters 29 | { 30 | get { return new int[] { 1, 2 }; } 31 | } 32 | } 33 | 34 | public class InvokeScript : ScriptBase 35 | { 36 | private IFunction m_script; 37 | private IFunction m_parameters = null; 38 | 39 | public InvokeScript(IFunction script) 40 | { 41 | m_script = script; 42 | } 43 | 44 | public InvokeScript(IFunction script, IFunction parameters) 45 | : this(script) 46 | { 47 | m_parameters = parameters; 48 | } 49 | 50 | public override string Save(Context c) 51 | { 52 | string parameters = (m_parameters == null) ? null : m_parameters.Save(c); 53 | if (string.IsNullOrEmpty(parameters)) 54 | { 55 | return SaveScript("invoke", m_script.Save(c)); 56 | } 57 | else 58 | { 59 | return SaveScript("invoke", m_script.Save(c), parameters); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Compiler/Scripts/IScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public interface IScript 9 | { 10 | string Line { get; set; } 11 | string Save(Context c); 12 | string Keyword { get; } 13 | } 14 | 15 | public interface IScriptConstructor 16 | { 17 | string Keyword { get; } 18 | IScript Create(string script, Element proc); 19 | IScriptFactory ScriptFactory { set; } 20 | GameLoader GameLoader { set; } 21 | } 22 | 23 | public abstract class ScriptBase : IScript 24 | { 25 | private string m_line; 26 | 27 | public override string ToString() 28 | { 29 | return "Script: " + Line; 30 | } 31 | 32 | protected string SaveScript(string keyword, params string[] args) 33 | { 34 | return keyword + " (" + String.Join(", ", args) + ");"; 35 | } 36 | 37 | protected string SaveExpressionScript(string keyword, IScript script, Context c, params string[] args) 38 | { 39 | string result; 40 | if (args.Length == 0) 41 | { 42 | result = keyword; 43 | } 44 | else 45 | { 46 | result = keyword + " (" + String.Join(", ", args) + ")"; 47 | } 48 | string scriptString = script != null ? script.Save(c) : string.Empty; 49 | return result + " {" + Environment.NewLine + scriptString + Environment.NewLine + "}"; 50 | } 51 | 52 | public Element Owner { get; set; } 53 | 54 | public abstract string Save(Context c); 55 | 56 | public virtual string Line 57 | { 58 | get { return m_line; } 59 | set { m_line = value; } 60 | } 61 | 62 | public virtual string Keyword 63 | { 64 | get 65 | { 66 | throw new NotImplementedException(); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Settings.config 2 | 3 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 4 | [Bb]in/ 5 | [Oo]bj/ 6 | 7 | # mstest test results 8 | TestResults 9 | 10 | ## Ignore Visual Studio temporary files, build results, and 11 | ## files generated by popular Visual Studio add-ons. 12 | 13 | # User-specific files 14 | *.suo 15 | *.user 16 | *.sln.docstates 17 | 18 | # Build results 19 | [Dd]ebug/ 20 | [Rr]elease/ 21 | x64/ 22 | *_i.c 23 | *_p.c 24 | *.ilk 25 | *.meta 26 | *.obj 27 | *.pch 28 | *.pdb 29 | *.pgc 30 | *.pgd 31 | *.rsp 32 | *.sbr 33 | *.tlb 34 | *.tli 35 | *.tlh 36 | *.tmp 37 | *.log 38 | *.vspscc 39 | *.vssscc 40 | .builds 41 | 42 | # Visual C++ cache files 43 | ipch/ 44 | *.aps 45 | *.ncb 46 | *.opensdf 47 | *.sdf 48 | 49 | # Visual Studio profiler 50 | *.psess 51 | *.vsp 52 | *.vspx 53 | 54 | # Guidance Automation Toolkit 55 | *.gpState 56 | 57 | # ReSharper is a .NET coding add-in 58 | _ReSharper* 59 | 60 | # NCrunch 61 | *.ncrunch* 62 | .*crunch*.local.xml 63 | 64 | # Installshield output folder 65 | [Ee]xpress 66 | 67 | # DocProject is a documentation generator add-in 68 | DocProject/buildhelp/ 69 | DocProject/Help/*.HxT 70 | DocProject/Help/*.HxC 71 | DocProject/Help/*.hhc 72 | DocProject/Help/*.hhk 73 | DocProject/Help/*.hhp 74 | DocProject/Help/Html2 75 | DocProject/Help/html 76 | 77 | # Click-Once directory 78 | publish 79 | 80 | # Publish Web Output 81 | *.Publish.xml 82 | 83 | # NuGet Packages Directory 84 | packages 85 | 86 | # Windows Azure Build Output 87 | csx 88 | *.build.csdef 89 | 90 | # Windows Store app package directory 91 | AppPackages/ 92 | 93 | # Others 94 | [Bb]in 95 | [Oo]bj 96 | sql 97 | TestResults 98 | [Tt]est[Rr]esult* 99 | *.Cache 100 | ClientBin 101 | [Ss]tyle[Cc]op.* 102 | ~$* 103 | *.dbmdl 104 | Generated_Code #added for RIA/Silverlight projects 105 | 106 | # Backup & report files from converting an old project file to a newer 107 | # Visual Studio version. Backup files are not needed, because we have git ;-) 108 | _UpgradeReport_Files/ 109 | Backup*/ 110 | UpgradeLog*.XML 111 | -------------------------------------------------------------------------------- /Compiler/Scripts/DoScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class DoScriptConstructor : ScriptConstructorBase 10 | { 11 | public override string Keyword 12 | { 13 | get { return "do"; } 14 | } 15 | 16 | protected override IScript CreateInt(List parameters) 17 | { 18 | switch (parameters.Count) 19 | { 20 | case 2: 21 | return new DoActionScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader)); 22 | case 3: 23 | return new DoActionScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader)); 24 | } 25 | return null; 26 | } 27 | 28 | protected override int[] ExpectedParameters 29 | { 30 | get { return new int[] { 2, 3 }; } 31 | } 32 | } 33 | 34 | public class DoActionScript : ScriptBase 35 | { 36 | private IFunction m_obj; 37 | private IFunction m_action; 38 | private IFunction m_parameters = null; 39 | 40 | public DoActionScript(IFunction obj, IFunction action) 41 | { 42 | m_obj = obj; 43 | m_action = action; 44 | } 45 | 46 | public DoActionScript(IFunction obj, IFunction action, IFunction parameters) 47 | : this(obj, action) 48 | { 49 | m_parameters = parameters; 50 | } 51 | 52 | public override string Save(Context c) 53 | { 54 | string parameters = (m_parameters == null) ? null : m_parameters.Save(c); 55 | if (!string.IsNullOrEmpty(parameters)) 56 | { 57 | return SaveScript("runscriptattribute3", m_obj.Save(c), m_action.Save(c), m_parameters.Save(c)); 58 | } 59 | else 60 | { 61 | return SaveScript("runscriptattribute2", m_obj.Save(c), m_action.Save(c)); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Compiler/Scripts/PlaySoundScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class PlaySoundScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "play sound"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new PlaySoundScript( 18 | new Expression(parameters[0], GameLoader), 19 | new Expression(parameters[1], GameLoader), 20 | new Expression(parameters[2], GameLoader)); 21 | } 22 | 23 | protected override int[] ExpectedParameters 24 | { 25 | get { return new int[] { 3 }; } 26 | } 27 | } 28 | 29 | public class PlaySoundScript : ScriptBase 30 | { 31 | private IFunction m_filename; 32 | private IFunction m_synchronous; 33 | private IFunction m_loop; 34 | 35 | public PlaySoundScript(IFunction function, IFunction synchronous, IFunction loop) 36 | { 37 | m_filename = function; 38 | m_synchronous = synchronous; 39 | m_loop = loop; 40 | } 41 | 42 | public override string Save(Context c) 43 | { 44 | return SaveScript("playsound", m_filename.Save(c), m_synchronous.Save(c), m_loop.Save(c)); 45 | } 46 | } 47 | 48 | public class StopSoundScriptConstructor : ScriptConstructorBase 49 | { 50 | public override string Keyword 51 | { 52 | get { return "stop sound"; } 53 | } 54 | 55 | protected override IScript CreateInt(List parameters) 56 | { 57 | return new StopSoundScript(); 58 | } 59 | 60 | protected override int[] ExpectedParameters 61 | { 62 | get { return new int[] { 0 }; } 63 | } 64 | } 65 | 66 | public class StopSoundScript : ScriptBase 67 | { 68 | public StopSoundScript() 69 | { 70 | } 71 | 72 | public override string Save(Context c) 73 | { 74 | return "stopsound();"; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Compiler/Scripts/ListAddScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class ListAddScriptConstructor : ScriptConstructorBase 10 | { 11 | public override string Keyword 12 | { 13 | get { return "list add"; } 14 | } 15 | 16 | protected override IScript CreateInt(List parameters) 17 | { 18 | return new ListAddScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader)); 19 | } 20 | 21 | protected override int[] ExpectedParameters 22 | { 23 | get { return new int[] { 2 }; } 24 | } 25 | } 26 | 27 | public class ListAddScript : ScriptBase 28 | { 29 | private IFunction m_list; 30 | private IFunction m_value; 31 | 32 | public ListAddScript(IFunction list, IFunction value) 33 | { 34 | m_list = list; 35 | m_value = value; 36 | } 37 | 38 | public override string Save(Context c) 39 | { 40 | return SaveScript("listadd", m_list.Save(c), m_value.Save(c)); 41 | } 42 | } 43 | 44 | public class ListRemoveScriptConstructor : ScriptConstructorBase 45 | { 46 | public override string Keyword 47 | { 48 | get { return "list remove"; } 49 | } 50 | 51 | protected override IScript CreateInt(List parameters) 52 | { 53 | return new ListRemoveScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader)); 54 | } 55 | 56 | protected override int[] ExpectedParameters 57 | { 58 | get { return new int[] { 2 }; } 59 | } 60 | } 61 | 62 | public class ListRemoveScript : ScriptBase 63 | { 64 | private IFunction m_list; 65 | private IFunction m_value; 66 | 67 | public ListRemoveScript(IFunction list, IFunction value) 68 | { 69 | m_list = list; 70 | m_value = value; 71 | } 72 | 73 | public override string Save(Context c) 74 | { 75 | return SaveScript("listremove", m_list.Save(c), m_value.Save(c)); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Compiler/Scripts/ScriptConstructorBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public abstract class ScriptConstructorBase : IScriptConstructor 9 | { 10 | public abstract string Keyword { get; } 11 | 12 | public IScript Create(string script, Element proc) 13 | { 14 | List parameters = null; 15 | string param = Utility.GetParameter(script); 16 | 17 | int numParams; 18 | if (param == null) 19 | { 20 | numParams = 0; 21 | } 22 | else 23 | { 24 | parameters = Utility.SplitParameter(param); 25 | numParams = parameters.Count; 26 | } 27 | 28 | if (ExpectedParameters.Count() > 0) 29 | { 30 | if (!ExpectedParameters.Contains(numParams)) 31 | { 32 | throw new Exception(string.Format("Expected {0} parameter(s)", FormatExpectedParameters(), script)); 33 | } 34 | } 35 | 36 | if (!RequireProcedure) 37 | { 38 | return CreateInt(parameters); 39 | } 40 | else 41 | { 42 | return CreateInt(parameters, proc); 43 | } 44 | } 45 | 46 | public IScriptFactory ScriptFactory { get; set; } 47 | 48 | public GameLoader GameLoader { get; set; } 49 | 50 | protected abstract IScript CreateInt(List parameters); 51 | 52 | protected virtual IScript CreateInt(List parameters, Element proc) 53 | { 54 | // only overridden for "return" script 55 | return null; 56 | } 57 | 58 | protected virtual bool RequireProcedure 59 | { 60 | get { return false; } 61 | } 62 | 63 | protected abstract int[] ExpectedParameters { get; } 64 | 65 | private string FormatExpectedParameters() 66 | { 67 | string result = ""; 68 | foreach (int i in ExpectedParameters) 69 | { 70 | result += i.ToString() + ","; 71 | } 72 | return result.Substring(0, result.Length - 1); 73 | } 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Compiler/Scripts/ShowMenuScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class ShowMenuScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "show menu"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string afterExpr; 18 | string param = Utility.GetParameter(script, out afterExpr); 19 | string callback = Utility.GetScript(afterExpr); 20 | 21 | string[] parameters = Utility.SplitParameter(param).ToArray(); 22 | if (parameters.Count() != 3) 23 | { 24 | throw new Exception(string.Format("'show menu' script should have 3 parameters: 'show menu ({0})'", param)); 25 | } 26 | IScript callbackScript = ScriptFactory.CreateScript(callback); 27 | 28 | return new ShowMenuScript(ScriptFactory, new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader), callbackScript); 29 | } 30 | 31 | public IScriptFactory ScriptFactory { get; set; } 32 | 33 | public GameLoader GameLoader { get; set; } 34 | } 35 | 36 | public class ShowMenuScript : ScriptBase 37 | { 38 | private IFunction m_caption; 39 | private IFunction m_options; 40 | private IFunction m_allowCancel; 41 | private IScript m_callbackScript; 42 | private IScriptFactory m_scriptFactory; 43 | 44 | public ShowMenuScript(IScriptFactory scriptFactory, IFunction caption, IFunction options, IFunction allowCancel, IScript callbackScript) 45 | { 46 | m_scriptFactory = scriptFactory; 47 | m_caption = caption; 48 | m_options = options; 49 | m_allowCancel = allowCancel; 50 | m_callbackScript = callbackScript; 51 | } 52 | 53 | public override string Save(Context c) 54 | { 55 | return string.Format("showmenu_async ({0}, {1}, {2}, function(result) {{ {3} }});", 56 | m_caption.Save(c), 57 | m_options.Save(c), 58 | m_allowCancel.Save(c), 59 | m_callbackScript.Save(c) 60 | ); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /QuestCompiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("QuestCompiler")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Text Adventures Ltd")] 14 | [assembly: AssemblyProduct("Quest Compiler")] 15 | [assembly: AssemblyCopyright("Copyright © 2013 Text Adventures Ltd")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("6.0.*")] -------------------------------------------------------------------------------- /Compiler/GameSaver/GameSaver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using TextAdventures.Quest.Scripts; 6 | 7 | namespace TextAdventures.Quest 8 | { 9 | interface IElementSaver 10 | { 11 | ElementType AppliesTo { get; } 12 | void Save(Element e, GameWriter writer); 13 | } 14 | 15 | public class GameSaver 16 | { 17 | private Dictionary m_elements; 18 | private Dictionary m_elementSavers = new Dictionary(); 19 | 20 | public class ProgressEventArgs : EventArgs 21 | { 22 | public int PercentComplete { get; set; } 23 | } 24 | 25 | public event EventHandler Progress; 26 | 27 | public GameSaver(Dictionary elements) 28 | { 29 | m_elements = elements; 30 | 31 | // Use Reflection to create instances of all IElementSavers (save individual elements) 32 | foreach (Type t in TextAdventures.Utility.Classes.GetImplementations(System.Reflection.Assembly.GetExecutingAssembly(), 33 | typeof(IElementSaver))) 34 | { 35 | AddElementSaver((IElementSaver)Activator.CreateInstance(t)); 36 | } 37 | } 38 | 39 | private void AddElementSaver(IElementSaver saver) 40 | { 41 | m_elementSavers.Add(saver.AppliesTo, saver); 42 | } 43 | 44 | public string Save() 45 | { 46 | int total = m_elements.Count; 47 | int done = 0; 48 | 49 | GameWriter writer = new GameWriter(); 50 | foreach (Element e in m_elements.Values) 51 | { 52 | if (Progress != null) 53 | { 54 | Progress(this, new ProgressEventArgs { PercentComplete = (int)(((double)done / total) * 100) }); 55 | } 56 | 57 | IElementSaver saver; 58 | if (m_elementSavers.TryGetValue(e.ElemType, out saver)) 59 | { 60 | saver.Save(e, writer); 61 | } 62 | else 63 | { 64 | throw new Exception("ERROR: No ElementSaver for type " + e.ElemType.ToString()); 65 | } 66 | done++; 67 | } 68 | return writer.Save(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Compiler/GameSaver/GameWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | internal class GameWriter 9 | { 10 | private StringBuilder data = new StringBuilder(); 11 | private Dictionary postElementScript = new Dictionary(); 12 | private List writtenElements = new List(); 13 | 14 | public void AddLine(string line) 15 | { 16 | data.AppendLine(EncodeNonAsciiCharacters(line)); 17 | } 18 | 19 | public string Save() 20 | { 21 | return data.ToString(); 22 | } 23 | 24 | public void AddPostElementScript(Element element, string script) 25 | { 26 | string result = string.Empty; 27 | if (postElementScript.ContainsKey(element)) 28 | { 29 | result = postElementScript[element] + Environment.NewLine; 30 | } 31 | result += script; 32 | 33 | postElementScript[element] = result; 34 | } 35 | 36 | public string GetPostElementScript(Element element) 37 | { 38 | if (!postElementScript.ContainsKey(element)) 39 | { 40 | return string.Empty; 41 | } 42 | return postElementScript[element]; 43 | } 44 | 45 | public void MarkElementWritten(Element element) 46 | { 47 | writtenElements.Add(element); 48 | } 49 | 50 | public bool IsElementWritten(Element element) 51 | { 52 | return writtenElements.Contains(element); 53 | } 54 | 55 | // from http://stackoverflow.com/questions/1615559/converting-unicode-strings-to-escaped-ascii-string 56 | private string EncodeNonAsciiCharacters(string value) 57 | { 58 | StringBuilder sb = new StringBuilder(); 59 | foreach (char c in value) 60 | { 61 | if (c > 127) 62 | { 63 | // This character is too big for ASCII 64 | string encodedValue = "\\u" + ((int)c).ToString("x4"); 65 | sb.Append(encodedValue); 66 | } 67 | else 68 | { 69 | sb.Append(c); 70 | } 71 | } 72 | return sb.ToString(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Compiler/QuestList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | public class QuestList : IList 9 | { 10 | private List m_list; 11 | 12 | public QuestList() 13 | : this(null) 14 | { 15 | } 16 | 17 | public QuestList(IEnumerable values) 18 | { 19 | if (values == null) 20 | { 21 | m_list = new List(); 22 | } 23 | else 24 | { 25 | m_list = new List(values); 26 | } 27 | } 28 | 29 | public int IndexOf(T item) 30 | { 31 | return m_list.IndexOf(item); 32 | } 33 | 34 | public void Insert(int index, T item) 35 | { 36 | m_list.Insert(index, item); 37 | } 38 | 39 | public void RemoveAt(int index) 40 | { 41 | m_list.RemoveAt(index); 42 | } 43 | 44 | public T this[int index] 45 | { 46 | get 47 | { 48 | return m_list[index]; 49 | } 50 | set 51 | { 52 | m_list[index] = value; 53 | } 54 | } 55 | 56 | public void Add(T item) 57 | { 58 | m_list.Add(item); 59 | } 60 | 61 | public void Clear() 62 | { 63 | m_list.Clear(); 64 | } 65 | 66 | public bool Contains(T item) 67 | { 68 | return m_list.Contains(item); 69 | } 70 | 71 | public void CopyTo(T[] array, int arrayIndex) 72 | { 73 | m_list.CopyTo(array, arrayIndex); 74 | } 75 | 76 | public int Count 77 | { 78 | get { return m_list.Count; } 79 | } 80 | 81 | public bool IsReadOnly 82 | { 83 | get { return ((IList)m_list).IsReadOnly; } 84 | } 85 | 86 | public bool Remove(T item) 87 | { 88 | return m_list.Remove(item); 89 | } 90 | 91 | public IEnumerator GetEnumerator() 92 | { 93 | return m_list.GetEnumerator(); 94 | } 95 | 96 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 97 | { 98 | return m_list.GetEnumerator(); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Compiler/Scripts/JSScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class JSScriptConstructor : IScriptConstructor 10 | { 11 | private static List s_prefixFunctions = new List 12 | { 13 | "StartOutputSection", 14 | "EndOutputSection", 15 | "HideOutputSection" 16 | }; 17 | 18 | public string Keyword 19 | { 20 | get { return "JS."; } 21 | } 22 | 23 | private static Regex s_jsFunctionName = new Regex(@"^JS\.([\w\.\@]*)"); 24 | 25 | public IScript Create(string script, Element proc) 26 | { 27 | var param = Utility.GetParameter(script); 28 | 29 | List expressions = null; 30 | 31 | if (param != null) 32 | { 33 | var parameters = Utility.SplitParameter(param); 34 | if (parameters.Count != 1 || parameters[0].Trim().Length != 0) 35 | { 36 | expressions = new List(parameters.Select(p => new Expression(p, GameLoader))); 37 | } 38 | } 39 | 40 | if (!s_jsFunctionName.IsMatch(script)) 41 | { 42 | throw new Exception(string.Format("Invalid JS function name in '{0}'", script)); 43 | } 44 | 45 | var functionName = s_jsFunctionName.Match(script).Groups[1].Value; 46 | 47 | if (s_prefixFunctions.Contains(functionName)) 48 | { 49 | functionName = "Js" + functionName; 50 | } 51 | 52 | return new JSScript(functionName, expressions); 53 | } 54 | 55 | public IScriptFactory ScriptFactory { set; private get; } 56 | public GameLoader GameLoader { set; private get; } 57 | } 58 | 59 | public class JSScript : ScriptBase 60 | { 61 | private string m_function; 62 | private List m_parameters; 63 | 64 | public JSScript(string function, List parameters) 65 | { 66 | m_function = function; 67 | m_parameters = parameters; 68 | } 69 | 70 | public override string Save(Context c) 71 | { 72 | return string.Format("{0} ({1})", m_function, m_parameters == null ? string.Empty : string.Join(", ", m_parameters.Select(p => p.Save(c)))); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Compiler/Scripts/DictionaryAddScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class DictionaryAddScriptConstructor : ScriptConstructorBase 10 | { 11 | public override string Keyword 12 | { 13 | get { return "dictionary add"; } 14 | } 15 | 16 | protected override IScript CreateInt(List parameters) 17 | { 18 | return new DictionaryAddScript( 19 | new Expression(parameters[0], GameLoader), 20 | new Expression(parameters[1], GameLoader), 21 | new Expression(parameters[2], GameLoader)); 22 | } 23 | 24 | protected override int[] ExpectedParameters 25 | { 26 | get { return new int[] { 3 }; } 27 | } 28 | } 29 | 30 | public class DictionaryAddScript : ScriptBase 31 | { 32 | private IFunction m_dictionary; 33 | private IFunction m_key; 34 | private IFunction m_value; 35 | 36 | public DictionaryAddScript(IFunction dictionary, IFunction key, IFunction value) 37 | { 38 | m_dictionary = dictionary; 39 | m_key = key; 40 | m_value = value; 41 | } 42 | 43 | public override string Save(Context c) 44 | { 45 | return SaveScript("dictionaryadd", m_dictionary.Save(c), m_key.Save(c), m_value.Save(c)); 46 | } 47 | } 48 | 49 | public class DictionaryRemoveScriptConstructor : ScriptConstructorBase 50 | { 51 | public override string Keyword 52 | { 53 | get { return "dictionary remove"; } 54 | } 55 | 56 | protected override IScript CreateInt(List parameters) 57 | { 58 | return new DictionaryRemoveScript( 59 | new Expression(parameters[0], GameLoader), 60 | new Expression(parameters[1], GameLoader)); 61 | } 62 | 63 | protected override int[] ExpectedParameters 64 | { 65 | get { return new int[] { 2 }; } 66 | } 67 | } 68 | 69 | public class DictionaryRemoveScript : ScriptBase 70 | { 71 | private IFunction m_dictionary; 72 | private IFunction m_key; 73 | 74 | public DictionaryRemoveScript(IFunction dictionary, IFunction key) 75 | { 76 | m_dictionary = dictionary; 77 | m_key = key; 78 | } 79 | 80 | public override string Save(Context c) 81 | { 82 | return SaveScript("dictionaryremove", m_dictionary.Save(c), m_key.Save(c)); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Compiler/Scripts/RunDelegateScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class RunDelegateScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "rundelegate"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | if (parameters.Count < 2) 18 | { 19 | throw new Exception("Expected at least 2 parameters in rundelegate call"); 20 | } 21 | 22 | List paramExpressions = new List(); 23 | IFunction obj = null; 24 | int cnt = 0; 25 | IFunction delegateName = null; 26 | 27 | foreach (string param in parameters) 28 | { 29 | cnt++; 30 | switch (cnt) 31 | { 32 | case 1: 33 | obj = new Expression(param, GameLoader); 34 | break; 35 | case 2: 36 | delegateName = new Expression(param, GameLoader); 37 | break; 38 | default: 39 | paramExpressions.Add(new Expression(param, GameLoader)); 40 | break; 41 | } 42 | } 43 | 44 | return new RunDelegateScript(obj, delegateName, paramExpressions); 45 | } 46 | 47 | protected override int[] ExpectedParameters 48 | { 49 | get { return new int[] { }; } 50 | } 51 | } 52 | 53 | public class RunDelegateScript : ScriptBase 54 | { 55 | private IFunction m_delegate; 56 | private FunctionCallParameters m_parameters; 57 | private IFunction m_appliesTo = null; 58 | 59 | public RunDelegateScript(IFunction obj, IFunction del, IList parameters) 60 | { 61 | m_delegate = del; 62 | m_parameters = new FunctionCallParameters(parameters); 63 | m_appliesTo = obj; 64 | } 65 | 66 | public override string Save(Context c) 67 | { 68 | List saveParameters = new List(); 69 | saveParameters.Add(m_appliesTo.Save(c)); 70 | saveParameters.Add(m_delegate.Save(c)); 71 | foreach (IFunction p in m_parameters.Parameters) 72 | { 73 | saveParameters.Add(p.Save(c)); 74 | } 75 | 76 | return SaveScript("rundelegate", saveParameters.ToArray()); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Compiler/Scripts/FirstTimeScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class FirstTimeScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "firsttime"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | // Get script after "firsttime" keyword 18 | script = script.Substring(9).Trim(); 19 | string firstTime = Utility.GetScript(script); 20 | IScript firstTimeScript = ScriptFactory.CreateScript(firstTime); 21 | 22 | return new FirstTimeScript(firstTimeScript); 23 | } 24 | 25 | public static void AddOtherwiseScript(IScript firstTimeScript, string script, IScriptFactory scriptFactory) 26 | { 27 | // Get script after "otherwise" keyword 28 | script = script.Substring(9).Trim(); 29 | string otherwise = Utility.GetScript(script); 30 | IScript otherwiseScript = scriptFactory.CreateScript(otherwise); 31 | ((FirstTimeScript)firstTimeScript).SetOtherwiseScript(otherwiseScript); 32 | } 33 | 34 | public IScriptFactory ScriptFactory { get; set; } 35 | public GameLoader GameLoader { get; set; } 36 | } 37 | 38 | public class FirstTimeScript : ScriptBase 39 | { 40 | private IScript m_firstTimeScript; 41 | private IScript m_otherwiseScript; 42 | private int m_id; 43 | private static int s_lastId = 0; 44 | 45 | public FirstTimeScript(IScript firstTimeScript) 46 | { 47 | s_lastId++; 48 | m_id = s_lastId; 49 | m_firstTimeScript = firstTimeScript; 50 | } 51 | 52 | internal void SetOtherwiseScript(IScript script) 53 | { 54 | m_otherwiseScript = script; 55 | } 56 | 57 | public override string Save(Context c) 58 | { 59 | string result = "if (!HasAttribute(GetObject(\"game\"), \"_firstTimeScriptsRun\")) set (GetObject(\"game\"), \"_firstTimeScriptsRun\", NewStringList());\n"; 60 | result += string.Format("if ($.inArray(\"{0}\", GetObject(\"game\")._firstTimeScriptsRun) == -1) {{\n", m_id); 61 | result += string.Format("listadd(GetObject(\"game\")._firstTimeScriptsRun, \"{0}\");\n", m_id); 62 | result += m_firstTimeScript.Save(c); 63 | result += "}\n"; 64 | 65 | if (m_otherwiseScript != null) 66 | { 67 | result += string.Format("else {{ {0} }}", m_otherwiseScript.Save(c)); 68 | } 69 | 70 | return result; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Compiler/Scripts/ForScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class ForScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "for"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string afterExpr; 18 | string param = Utility.GetParameter(script, out afterExpr); 19 | string loop = Utility.GetScript(afterExpr); 20 | 21 | string[] parameters = Utility.SplitParameter(param).ToArray(); 22 | IScript loopScript = ScriptFactory.CreateScript(loop); 23 | 24 | if (parameters.Count() == 3) 25 | { 26 | return new ForScript(ScriptFactory, parameters[0], new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader), loopScript); 27 | } 28 | else if (parameters.Count() == 4) 29 | { 30 | return new ForScript(ScriptFactory, parameters[0], new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader), loopScript, new Expression(parameters[3], GameLoader)); 31 | } 32 | else 33 | { 34 | throw new Exception(string.Format("'for' script should have 3 or 4 parameters: 'for ({0})'", param)); 35 | } 36 | } 37 | 38 | public IScriptFactory ScriptFactory { get; set; } 39 | 40 | public GameLoader GameLoader { get; set; } 41 | } 42 | 43 | public class ForScript : ScriptBase 44 | { 45 | private IFunction m_from; 46 | private IFunction m_to; 47 | private IScript m_loopScript; 48 | private string m_variable; 49 | private IScriptFactory m_scriptFactory; 50 | private IFunction m_step; 51 | 52 | public ForScript(IScriptFactory scriptFactory, string variable, IFunction from, IFunction to, IScript loopScript) 53 | : this(scriptFactory, variable, from, to, loopScript, null) 54 | { 55 | } 56 | 57 | public ForScript(IScriptFactory scriptFactory, string variable, IFunction from, IFunction to, IScript loopScript, IFunction step) 58 | { 59 | m_scriptFactory = scriptFactory; 60 | m_variable = variable; 61 | m_from = from; 62 | m_to = to; 63 | m_loopScript = loopScript; 64 | m_step = step; 65 | } 66 | 67 | public override string Save(Context c) 68 | { 69 | string step = (m_step == null) ? "++" : "+=" + m_step.Save(c); 70 | string result = string.Format("for (var {0} = {1}; {0} <= {2}; {0}{3}) {{\n", m_variable, m_from.Save(c), m_to.Save(c), step); 71 | result += m_loopScript.Save(c); 72 | result += Environment.NewLine + "}"; 73 | return result; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /QuestCompiler/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Debug mode 39 | Minify 40 | Gamebook 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /QuestCompiler/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace QuestCompiler.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("QuestCompiler.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /CompilerTests/ExpressionTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | using TextAdventures.Quest; 7 | using Moq; 8 | 9 | namespace CompilerTests 10 | { 11 | [TestClass] 12 | public class ExpressionTests 13 | { 14 | Mock gameLoader; 15 | 16 | [TestInitialize] 17 | public void Init() 18 | { 19 | gameLoader = new Mock(); 20 | gameLoader.Setup(l => l.Elements).Returns(new Dictionary { { "myobject", new Element(ElementType.Object, gameLoader.Object) } }); 21 | } 22 | 23 | [TestMethod] 24 | public void TestSave() 25 | { 26 | Expression testExpression = new Expression("myexpression", gameLoader.Object); 27 | Assert.AreEqual("myexpression", testExpression.Save(new Context())); 28 | } 29 | 30 | [TestMethod] 31 | public void TestNot() 32 | { 33 | Expression testExpression = new Expression("not myexpression", gameLoader.Object); 34 | Assert.AreEqual("!(myexpression)", testExpression.Save(new Context())); 35 | } 36 | 37 | [TestMethod] 38 | public void TestEquals() 39 | { 40 | Expression testExpression = new Expression("one = two", gameLoader.Object); 41 | Assert.AreEqual("one == two", testExpression.Save(new Context())); 42 | } 43 | 44 | [TestMethod] 45 | public void TestNotEquals() 46 | { 47 | Expression testExpression = new Expression("one <> two", gameLoader.Object); 48 | Assert.AreEqual("one != two", testExpression.Save(new Context())); 49 | } 50 | 51 | [TestMethod] 52 | public void TestGreaterEquals() 53 | { 54 | Expression testExpression = new Expression("one >= two", gameLoader.Object); 55 | Assert.AreEqual("one >= two", testExpression.Save(new Context())); 56 | } 57 | 58 | [TestMethod] 59 | public void TestReplaceReservedKeywords() 60 | { 61 | Expression testExpression = new Expression("one + var", gameLoader.Object); 62 | Assert.AreEqual("one + variable_var", testExpression.Save(new Context())); 63 | } 64 | 65 | [TestMethod] 66 | public void TestReplaceOverloadedFunctions() 67 | { 68 | Expression testExpression = new Expression("TypeOf(value)", gameLoader.Object); 69 | Assert.AreEqual("overloadedFunctions.TypeOf(value)", testExpression.Save(new Context())); 70 | 71 | Expression testExpression2 = new Expression("(TypeOf(element[attribute]) = \"script\")", gameLoader.Object); 72 | Assert.AreEqual("(overloadedFunctions.TypeOf(element[attribute]) == \"script\")", testExpression2.Save(new Context())); 73 | } 74 | 75 | [TestMethod] 76 | public void TestSpaceReplacement() 77 | { 78 | Expression testExpression = new Expression("object.my attribute", gameLoader.Object); 79 | Assert.AreEqual(string.Format("object.my{0}attribute", Utility.SpaceReplacementString), testExpression.Save(new Context())); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Compiler/Scripts/RequestScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class RequestScriptConstructor : ScriptConstructorBase 10 | { 11 | public override string Keyword 12 | { 13 | get { return "request"; } 14 | } 15 | 16 | protected override IScript CreateInt(List parameters) 17 | { 18 | return new RequestScript(parameters[0], new Expression(parameters[1], GameLoader)); 19 | } 20 | 21 | protected override int[] ExpectedParameters 22 | { 23 | get { return new int[] { 2 }; } 24 | } 25 | } 26 | 27 | public class RequestScript : ScriptBase 28 | { 29 | private string m_request; 30 | private IFunction m_data; 31 | 32 | private static List s_ignoreFunctions = new List 33 | { 34 | "SetMenuBackground", 35 | "SetMenuForeground", 36 | "SetMenuHoverBackground", 37 | "SetMenuHoverForeground", 38 | "SetMenuFontName", 39 | "SetMenuFontSize" 40 | }; 41 | 42 | public RequestScript(string request, IFunction data) 43 | { 44 | m_data = data; 45 | m_request = request; 46 | } 47 | 48 | private static Regex s_runScript = new Regex("\"(.*); *\" \\+ (.*)"); 49 | 50 | public override string Save(Context c) 51 | { 52 | if (m_request == "RunScript") 53 | { 54 | string data = m_data.Save(c); 55 | if (s_runScript.IsMatch(data)) 56 | { 57 | Match result = s_runScript.Match(data); 58 | if (s_ignoreFunctions.Contains(result.Groups[1].Value)) 59 | { 60 | // ignore the hyperlink menu formatting functions. 61 | // TO DO: Should only ignore these in web profile. 62 | return string.Empty; 63 | } 64 | return string.Format("{0}({1});", result.Groups[1].Value, result.Groups[2].Value); 65 | } 66 | else 67 | { 68 | if (!data.StartsWith("\"") || !data.EndsWith("\"") || data.Substring(1, data.Length - 2).Contains("\"")) 69 | { 70 | throw new NotImplementedException("Unhandled RunScript conversion: " + data); 71 | } 72 | if (!data.Contains(";")) 73 | { 74 | return (data.Substring(1, data.Length - 2) + "();"); 75 | } 76 | else 77 | { 78 | var args = data.Substring(1, data.Length - 2).Split(';'); 79 | return args[0].Trim() + "(" + string.Join(",", args.Skip(1).Select(a => a.Trim()).ToArray()) + ")"; 80 | } 81 | } 82 | } 83 | else 84 | { 85 | return SaveScript("request", string.Format("\"{0}\"", m_request), m_data.Save(c)); 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /QuestJSWeb/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CompilerTests/CompilerTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 7 | 8 | 2.0 9 | {EE80BC14-47EF-4465-A758-11CC8A92E4DF} 10 | Library 11 | Properties 12 | CompilerTests 13 | CompilerTests 14 | v4.5 15 | 512 16 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | 40 | 41 | ..\Dependencies\Moq.dll 42 | 43 | 44 | 45 | 3.5 46 | 47 | 48 | 49 | 50 | False 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {64131651-5158-493D-A1CF-27C7575F2653} 61 | Compiler 62 | 63 | 64 | 65 | 72 | -------------------------------------------------------------------------------- /QuestJSWeb/web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Compiler/ElementFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | public class ElementFactory 9 | { 10 | private GameLoader m_loader; 11 | private Dictionary m_defaultTypeNames = new Dictionary(); 12 | 13 | public ElementFactory(GameLoader loader) 14 | { 15 | m_loader = loader; 16 | m_defaultTypeNames.Add(ObjectType.Object, "defaultobject"); 17 | m_defaultTypeNames.Add(ObjectType.Exit, "defaultexit"); 18 | m_defaultTypeNames.Add(ObjectType.Command, "defaultcommand"); 19 | m_defaultTypeNames.Add(ObjectType.Game, "defaultgame"); 20 | m_defaultTypeNames.Add(ObjectType.TurnScript, "defaultturnscript"); 21 | } 22 | 23 | public Element CreateCommand(string name) 24 | { 25 | return CreateObject(name, null, ObjectType.Command); 26 | } 27 | 28 | public Element CreateObject(string name) 29 | { 30 | return CreateObject(name, null, ObjectType.Object); 31 | } 32 | 33 | public Element CreateObject(string name, Element parent, ObjectType type) 34 | { 35 | Element result = CreateElement(ElementType.Object, name); 36 | result.Parent = parent; 37 | result.Type = type; 38 | result.Fields.AddTypeName(m_defaultTypeNames[type]); 39 | return result; 40 | } 41 | 42 | public Element CreateGame() 43 | { 44 | return CreateObject("game", null, ObjectType.Game); 45 | } 46 | 47 | public Element CreateTurnScript(string name, Element parent) 48 | { 49 | return CreateObject(name, parent, ObjectType.TurnScript); 50 | } 51 | 52 | public Element CreateFunction(string name) 53 | { 54 | return CreateElement(ElementType.Function, name); 55 | } 56 | 57 | public Element CreateElement(ElementType type, string name) 58 | { 59 | string mappedName = m_loader.NameMapper.AddToMap(name); 60 | Element result = new Element(type, m_loader); 61 | result.Name = name; 62 | result.MetaFields[MetaFieldDefinitions.MappedName] = mappedName; 63 | m_loader.AddElement(result); 64 | return result; 65 | } 66 | 67 | public Element CreateTemplate(string name, string text, bool isCommandTemplate) 68 | { 69 | string id = GetUniqueID("template"); 70 | Element template = CreateElement(ElementType.Template, id); 71 | template.Fields[FieldDefinitions.TemplateName] = name; 72 | template.Fields[FieldDefinitions.Text] = text; 73 | if (isCommandTemplate) 74 | { 75 | template.Fields[FieldDefinitions.IsVerb] = true; 76 | } 77 | return template; 78 | } 79 | 80 | private Dictionary m_nextUniqueID = new Dictionary(); 81 | 82 | public string GetUniqueID() 83 | { 84 | return GetUniqueID(null); 85 | } 86 | 87 | public string GetUniqueID(string prefix) 88 | { 89 | if (string.IsNullOrEmpty(prefix)) prefix = "k"; 90 | if (!m_nextUniqueID.ContainsKey(prefix)) 91 | { 92 | m_nextUniqueID.Add(prefix, 0); 93 | } 94 | 95 | m_nextUniqueID[prefix]++; 96 | return prefix + m_nextUniqueID[prefix].ToString(); 97 | } 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /QuestJSWeb/Controllers/CompileController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Web; 7 | using System.Web.Mvc; 8 | using Ionic.Zip; 9 | using Microsoft.WindowsAzure.Storage; 10 | using Microsoft.WindowsAzure.Storage.Blob; 11 | using QuestJSWeb.Models; 12 | using TextAdventures.Quest; 13 | 14 | namespace QuestJSWeb.Controllers 15 | { 16 | public class CompileController : Controller 17 | { 18 | public ActionResult Index() 19 | { 20 | return View(); 21 | } 22 | 23 | [HttpPost] 24 | public ActionResult Index(CompileModel model) 25 | { 26 | if (!ModelState.IsValid) 27 | { 28 | return View(model); 29 | } 30 | 31 | var tempFile = Path.GetTempFileName() + ".quest"; 32 | model.File.SaveAs(tempFile); 33 | 34 | var outputFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); 35 | Directory.CreateDirectory(outputFolder); 36 | 37 | var compiler = new Compiler(Server.MapPath("~/bin/Resources")); 38 | 39 | var result = compiler.Compile(new CompileOptions 40 | { 41 | Filename = tempFile, 42 | OutputFolder = outputFolder, 43 | Profile = "Web", 44 | Minify = false, 45 | DebugMode = false, 46 | Gamebook = true 47 | }); 48 | 49 | var resultModel = new CompileResult 50 | { 51 | Success = result.Success, 52 | Errors = result.Errors 53 | }; 54 | 55 | if (result.Success) 56 | { 57 | var guid = Guid.NewGuid().ToString(); 58 | UploadBlob("questjs-input", guid + "/input.quest", tempFile, false); 59 | 60 | var zipFilename = Path.GetTempFileName() + ".zip"; 61 | 62 | using (var zip = new ZipFile(zipFilename)) 63 | { 64 | zip.AddDirectory(outputFolder); 65 | zip.Save(); 66 | } 67 | 68 | var uri = UploadBlob("questjs", guid + "/html.zip", zipFilename, true); 69 | 70 | resultModel.DownloadUrl = uri; 71 | } 72 | 73 | return View("Result", resultModel); 74 | } 75 | 76 | private static string UploadBlob(string containerName, string filename, string file, bool publicContainer) 77 | { 78 | var container = GetAzureBlobContainer(containerName, publicContainer); 79 | var blob = container.GetBlockBlobReference(filename); 80 | blob.Properties.ContentType = "application/zip"; 81 | blob.UploadFromFile(file, FileMode.Open); 82 | return blob.Uri.ToString(); 83 | } 84 | 85 | private static CloudBlobContainer GetAzureBlobContainer(string containerName, bool isPublic) 86 | { 87 | var connectionString = ConfigurationManager.AppSettings["AzureConnectionString"]; 88 | var account = CloudStorageAccount.Parse(connectionString); 89 | 90 | var blobClient = account.CreateCloudBlobClient(); 91 | var container = blobClient.GetContainerReference(containerName); 92 | container.CreateIfNotExists(); 93 | container.SetPermissions(new BlobContainerPermissions 94 | { 95 | PublicAccess = isPublic ? BlobContainerPublicAccessType.Blob : BlobContainerPublicAccessType.Off, 96 | }); 97 | return container; 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /Compiler/Scripts/ForEachScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | 7 | namespace TextAdventures.Quest.Scripts 8 | { 9 | public class ForEachScriptConstructor : IScriptConstructor 10 | { 11 | public string Keyword 12 | { 13 | get { return "foreach"; } 14 | } 15 | 16 | public IScript Create(string script, Element proc) 17 | { 18 | string afterExpr; 19 | string param = Utility.GetParameter(script, out afterExpr); 20 | string loop = Utility.GetScript(afterExpr); 21 | 22 | string[] parameters = Utility.SplitParameter(param).ToArray(); 23 | if (parameters.Count() != 2) 24 | { 25 | throw new Exception(string.Format("'foreach' script should have 2 parameters: 'foreach ({0})'", param)); 26 | } 27 | IScript loopScript = ScriptFactory.CreateScript(loop); 28 | 29 | string type = parameters[0]; 30 | 31 | return new ForEachScript(parameters[0], new Expression(parameters[1], GameLoader), loopScript); 32 | } 33 | 34 | public IScriptFactory ScriptFactory { get; set; } 35 | 36 | public GameLoader GameLoader { get; set; } 37 | } 38 | 39 | public class ForEachScript : ScriptBase 40 | { 41 | private IFunction m_list; 42 | private IScript m_loopScript; 43 | private string m_variable; 44 | 45 | public ForEachScript(string variable, IFunction list, IScript loopScript) 46 | { 47 | m_variable = variable; 48 | m_list = list; 49 | m_loopScript = loopScript; 50 | } 51 | 52 | public override string Save(Context c) 53 | { 54 | string result = string.Empty; 55 | string list = m_list.Save(c); 56 | if (list.Contains("(")) 57 | { 58 | // if we're iterating over the results of a function, save the results to a variable first 59 | string iterateOver = list; 60 | list = string.Format("list_{0}", m_variable); 61 | result += string.Format("var {0} = {1};\n", list, iterateOver); 62 | } 63 | string arrayCheckVariable = list.Replace(".", "_") + "_isarray"; 64 | result += string.Format("var {0} = (Object.prototype.toString.call({1}) === '[object Array]');\n", arrayCheckVariable, list); 65 | result += string.Format("for (var iterator_{0} in {1}) {{\n", m_variable, list); 66 | string variableName = Utility.ReplaceReservedVariableNames(m_variable); 67 | // TO DO: Need some way of warning if variable name clashes with an object name 68 | //if (m_elements.ContainsKey(variableName)) 69 | //{ 70 | // AddWarning(string.Format("Variable '{0}' clashes with object name", variableName)); 71 | //} 72 | string scriptString = string.Format("var {0} = {3} ? {1}[iterator_{2}] : iterator_{2};\n", variableName, list, m_variable, arrayCheckVariable); 73 | if (m_loopScript != null) 74 | { 75 | // Dictionaries contain a dummy key so that TypeOf can tell between a string dictionary and an object dictionary. 76 | // We add a condition here so that the dummy key is excluded from a foreach loop. 77 | string loopScriptAndCondition = string.Format("if ({0} || iterator_{1}!=\"__dummyKey\") {{ {2} }}", arrayCheckVariable, m_variable, m_loopScript.Save(c)); 78 | scriptString += loopScriptAndCondition; 79 | } 80 | return result + scriptString + Environment.NewLine + "}"; 81 | } 82 | 83 | public override string Keyword 84 | { 85 | get 86 | { 87 | return "foreach"; 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Compiler/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | TO DO: Could also use conditional CSS here, then could use the same CSS file for WebPlayer 3 | See http://developer.apple.com/library/safari/#codinghowtos/Mobile/UserExperience/_index.html 4 | */ 5 | 6 | body 7 | { 8 | font-family: Arial, Helvetica, sans-serif; 9 | margin: 0px; 10 | background: $$BACKGROUND$$; 11 | } 12 | a.cmdlink 13 | { 14 | text-decoration: underline; 15 | color: Blue; 16 | cursor: pointer; 17 | } 18 | a.cmdlink.disabled 19 | { 20 | text-decoration: inherit; 21 | color: inherit !important; 22 | cursor: inherit; 23 | } 24 | h2 25 | { 26 | font-size: 110%; 27 | } 28 | div#gameBorder 29 | { 30 | margin-left: auto; 31 | margin-right: auto; 32 | margin-top: 0; 33 | } 34 | div#gamePanes 35 | { 36 | padding-bottom: 10px; 37 | background: white; 38 | } 39 | div#status 40 | { 41 | background: #E0E0FF; 42 | height: 20px; 43 | position: fixed; 44 | top: 0px; 45 | z-index: 100; 46 | width: 100%; 47 | margin-left: auto; 48 | margin-right: auto; 49 | font-size: 14pt; 50 | padding: 2px; 51 | } 52 | #dialog 53 | { 54 | display: none; 55 | } 56 | #msgbox 57 | { 58 | display: none; 59 | } 60 | .compassbutton 61 | { 62 | margin-right: 0; 63 | width: 50px; 64 | height: 50px; 65 | background-color: transparent; 66 | background-repeat: no-repeat; 67 | cursor: pointer; 68 | vertical-align: middle; 69 | background-position:center; 70 | } 71 | #statusVars 72 | { 73 | display: none; 74 | font-size: 80%; 75 | margin-bottom: 10px; 76 | padding-left: 10px; 77 | } 78 | .emptyListLabel 79 | { 80 | font-size: 80%; 81 | padding-left: 10px; 82 | } 83 | #gamePanesFinished 84 | { 85 | display: none; 86 | } 87 | div#divOutput 88 | { 89 | padding: 4px; 90 | margin: 0px; 91 | } 92 | #compassTable 93 | { 94 | padding-top: 60px; 95 | padding-bottom: 60px; 96 | } 97 | #txtCommand 98 | { 99 | width: 100%; 100 | margin-left: 0px; 101 | font-size: 14pt; 102 | height: inherit; 103 | } 104 | div#gameObjects 105 | { 106 | padding-bottom: 10px; 107 | background: white; 108 | } 109 | div#gameExits 110 | { 111 | background: white; 112 | } 113 | div#gameMore 114 | { 115 | background: white; 116 | } 117 | div#gameOptions 118 | { 119 | background: white; 120 | text-align: center; 121 | } 122 | select#selectOptions 123 | { 124 | font-size: 120%; 125 | } 126 | ul.elementList 127 | { 128 | list-style: none; 129 | padding: 0; 130 | border: 1px solid #ccc; 131 | margin: 0px 16px 16px 16px; 132 | } 133 | ul.elementList li 134 | { 135 | display: block; 136 | font-family: Helvetica, Arial, sans-serif; 137 | font-weight: bold; 138 | background-image: -webkit-gradient(linear,left top,left bottom,from(#fdfdfd),to(#eee)); 139 | border-bottom: 1px solid #ccc; 140 | padding: 10px 10px 10px 20px; 141 | } 142 | li.elementListHover 143 | { 144 | background-image: -webkit-gradient(linear,left top,left bottom,from(#fdfdff),to(#aaaaff)) !important; 145 | } 146 | li.last-child 147 | { 148 | border-bottom: 0 !important; 149 | } 150 | h2.paneHeader 151 | { 152 | font-size: 16px; 153 | text-align: center; 154 | color: White; 155 | background: black; 156 | display: block; 157 | margin: 0px 0px 10px 0px; 158 | padding: 10px; 159 | } 160 | div#aboutContent 161 | { 162 | padding: 0px 10px 10px 10px; 163 | font-size: 80%; 164 | } 165 | img 166 | { 167 | max-width: 100%; 168 | display: block; 169 | margin: 0 auto; 170 | } 171 | select.optionsList 172 | { 173 | font-size: 20px; 174 | } 175 | div#tabButton 176 | { 177 | font-size: 25px; 178 | } 179 | table#inputBar 180 | { 181 | width: 100%; 182 | } 183 | td#inputBarButtons 184 | { 185 | width: 35px; 186 | } 187 | input[type="text"] { 188 | -webkit-box-sizing: border-box; 189 | -moz-box-sizing: border-box; 190 | box-sizing: border-box; 191 | } -------------------------------------------------------------------------------- /Utility/JSInterop.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace TextAdventures.Utility.JSInterop 8 | { 9 | public static class JavaScriptParameterHelpers 10 | { 11 | public static string StringParameter(string param) 12 | { 13 | return string.Format("\"{0}\"", param.Replace("\"", "\\\"").Replace(Environment.NewLine, "\\n")); 14 | } 15 | } 16 | 17 | public interface IJavaScriptParameter 18 | { 19 | string GetParameter(); 20 | } 21 | 22 | public class StringParameter : IJavaScriptParameter 23 | { 24 | private string m_param; 25 | 26 | public StringParameter(string param) 27 | { 28 | if (param == null) param = string.Empty; 29 | m_param = param.Replace("\r", "").Replace("\n", ""); 30 | } 31 | 32 | public string GetParameter() 33 | { 34 | return JavaScriptParameterHelpers.StringParameter(m_param); 35 | } 36 | } 37 | 38 | public class NullParameter : IJavaScriptParameter 39 | { 40 | public string GetParameter() 41 | { 42 | return "null"; 43 | } 44 | } 45 | 46 | public class DictionaryParameter : IJavaScriptParameter 47 | { 48 | private IDictionary m_param; 49 | 50 | public DictionaryParameter(IDictionary param) 51 | { 52 | m_param = param; 53 | } 54 | 55 | public string GetParameter() 56 | { 57 | // Copy dictionary to work around an InvalidCastException when serializing 58 | Dictionary dictionary = new Dictionary(m_param); 59 | return Newtonsoft.Json.JsonConvert.SerializeObject(dictionary); 60 | } 61 | } 62 | 63 | public class JSONParameter : IJavaScriptParameter 64 | { 65 | private object m_param; 66 | 67 | public JSONParameter(object param) 68 | { 69 | m_param = param; 70 | } 71 | 72 | public string GetParameter() 73 | { 74 | return Newtonsoft.Json.JsonConvert.SerializeObject(m_param); 75 | } 76 | } 77 | 78 | public class BooleanParameter : IJavaScriptParameter 79 | { 80 | private bool m_param; 81 | 82 | public BooleanParameter(bool param) 83 | { 84 | m_param = param; 85 | } 86 | 87 | public string GetParameter() 88 | { 89 | return m_param ? "true" : "false"; 90 | } 91 | } 92 | 93 | public class IntParameter : IJavaScriptParameter 94 | { 95 | private int m_param; 96 | 97 | public IntParameter(int param) 98 | { 99 | m_param = param; 100 | } 101 | 102 | public string GetParameter() 103 | { 104 | return m_param.ToString(CultureInfo.InvariantCulture); 105 | } 106 | } 107 | 108 | public class DoubleParameter : IJavaScriptParameter 109 | { 110 | private double m_param; 111 | 112 | public DoubleParameter(double param) 113 | { 114 | m_param = param; 115 | } 116 | 117 | public string GetParameter() 118 | { 119 | return m_param.ToString(CultureInfo.InvariantCulture); 120 | } 121 | } 122 | 123 | public class StringArrayParameter : IJavaScriptParameter 124 | { 125 | private IEnumerable m_param; 126 | 127 | public StringArrayParameter(IEnumerable param) 128 | { 129 | m_param = param; 130 | } 131 | 132 | public string GetParameter() 133 | { 134 | string result = string.Empty; 135 | foreach (string param in m_param) 136 | { 137 | if (result.Length > 0) result += ", "; 138 | result += JavaScriptParameterHelpers.StringParameter(param); 139 | } 140 | return "[" + result + "]"; 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /Compiler/Expression.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace TextAdventures.Quest 8 | { 9 | public class Context 10 | { 11 | private List m_localVariables = new List(); 12 | 13 | public void AddLocalVariable(params string[] variables) 14 | { 15 | foreach (var variable in variables) 16 | { 17 | if (m_localVariables.Contains(variable)) continue; 18 | m_localVariables.Add(variable); 19 | } 20 | } 21 | 22 | public List LocalVariables { get { return m_localVariables; } } 23 | } 24 | 25 | public interface IFunction 26 | { 27 | string Save(Context c); 28 | } 29 | 30 | public class Expression : IFunction 31 | { 32 | private string m_expression; 33 | private GameLoader m_gameLoader; 34 | 35 | public Expression(string expression, GameLoader loader) 36 | { 37 | m_expression = expression; 38 | m_gameLoader = loader; 39 | if (loader == null) throw new ArgumentNullException(); 40 | } 41 | 42 | public string Save(Context c) 43 | { 44 | // call utility function, pass in obj names, to convert obj references to object_objectname 45 | // also needs to remove spaces in object or variable names 46 | // also convert "and" &&, "or" ||, "not" !, "xor" ^ 47 | // and "=" must be "==", also check what not-equals operator is in FLEE, convert to != if necessary 48 | 49 | string result = m_expression; 50 | //result = Utility.ReplaceObjectNames(result, m_gameLoader.ElementNamesRegexes); 51 | result = Utility.ReplaceRespectingQuotes(result, " and ", " && "); 52 | result = Utility.ReplaceRespectingQuotes(result, " or ", " || "); 53 | result = Utility.ReplaceRespectingQuotes(result, " xor ", " ^ "); 54 | result = Utility.ReplaceRespectingQuotes(result, "True", "true"); 55 | result = Utility.ReplaceRespectingQuotes(result, "False", "false"); 56 | // replace = with ==, but leave >= and <= alone 57 | result = Utility.ReplaceRegexMatchesRespectingQuotes(result, new Regex(@"([^<>])="), "$1==", false); 58 | result = Utility.ReplaceRespectingQuotes(result, "<>", "!="); 59 | result = ReplaceNotConditions(result); 60 | result = Utility.ReplaceRegexMatchesRespectingQuotes(result, new Regex(@"\bnot "), "!", false); 61 | result = Utility.ReplaceReservedVariableNames(result); 62 | result = Utility.ReplaceOverloadedFunctionNames(result); 63 | result = Utility.ReplaceObjectNames(result, m_gameLoader.ElementNamesRegexes, c.LocalVariables); 64 | result = Utility.ConvertVariableNamesWithSpaces(result); 65 | 66 | return result; 67 | } 68 | 69 | private static Regex s_conditionDelimitersRegex = new Regex(@"(&&|\|\|)"); 70 | 71 | private string ReplaceNotConditions(string input) 72 | { 73 | string[] conditions = s_conditionDelimitersRegex.Split(input); 74 | string result = string.Empty; 75 | 76 | bool isDelimiter = true; 77 | 78 | foreach (string condition in conditions) 79 | { 80 | isDelimiter = !isDelimiter; 81 | 82 | if (isDelimiter) 83 | { 84 | result += condition; 85 | } 86 | else 87 | { 88 | if (condition.Trim().StartsWith("not ")) 89 | { 90 | int idx = condition.IndexOf("not "); 91 | result += condition.Substring(0, idx + 4) + "(" + condition.Substring(idx + 4) + ")"; 92 | } 93 | else 94 | { 95 | result += condition; 96 | } 97 | } 98 | } 99 | 100 | return result; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Compiler/Scripts/FunctionCallScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class FunctionCallScriptConstructor : IScriptConstructor 9 | { 10 | public IScript Create(string script, Element proc) 11 | { 12 | List paramExpressions = null; 13 | string procName, afterParameter; 14 | 15 | string param = Utility.GetParameter(script, out afterParameter); 16 | IScript paramScript = null; 17 | 18 | // Handle functions of the form 19 | // SomeFunction (parameter) { script } 20 | if (afterParameter != null) 21 | { 22 | afterParameter = afterParameter.Trim(); 23 | if (afterParameter.Length > 0) 24 | { 25 | string paramScriptString = Utility.GetScript(afterParameter); 26 | paramScript = ScriptFactory.CreateScript(paramScriptString); 27 | } 28 | } 29 | 30 | if (param == null && paramScript == null) 31 | { 32 | procName = script; 33 | } 34 | else 35 | { 36 | if (param != null) 37 | { 38 | List parameters = Utility.SplitParameter(param); 39 | procName = script.Substring(0, script.IndexOf('(')).Trim(); 40 | paramExpressions = new List(); 41 | if (param.Trim().Length > 0) 42 | { 43 | foreach (string s in parameters) 44 | { 45 | paramExpressions.Add(new Expression(s, GameLoader)); 46 | } 47 | } 48 | } 49 | else 50 | { 51 | procName = script.Substring(0, script.IndexOfAny(new char[] { '{', ' ' })); 52 | } 53 | } 54 | 55 | return new FunctionCallScript(GameLoader, procName, paramExpressions, paramScript); 56 | } 57 | 58 | public IScriptFactory ScriptFactory { get; set; } 59 | public GameLoader GameLoader { get; set; } 60 | 61 | public string Keyword 62 | { 63 | get { return null; } 64 | } 65 | } 66 | 67 | public class FunctionCallScript : ScriptBase 68 | { 69 | private string m_procedure; 70 | private FunctionCallParameters m_parameters; 71 | private IScript m_paramFunction; 72 | private GameLoader m_loader; 73 | 74 | public FunctionCallScript(GameLoader loader, string procedure) 75 | : this(loader, procedure, null, null) 76 | { 77 | } 78 | 79 | public FunctionCallScript(GameLoader loader, string procedure, IList parameters, IScript paramFunction) 80 | { 81 | m_loader = loader; 82 | m_procedure = procedure.Replace(" ", Utility.SpaceReplacementString); 83 | m_parameters = new FunctionCallParameters(parameters); 84 | m_paramFunction = paramFunction; 85 | } 86 | 87 | public override string Save(Context c) 88 | { 89 | if (!m_loader.Elements.ContainsKey(m_procedure.Replace(Utility.SpaceReplacementString, " "))) 90 | { 91 | throw new Exception(string.Format("Unknown function '{0}'", m_procedure)); 92 | } 93 | 94 | if ((m_parameters == null || m_parameters.Parameters == null || m_parameters.Parameters.Count == 0) && m_paramFunction == null) 95 | { 96 | return m_procedure + "();"; 97 | } 98 | 99 | List parameters = new List(); 100 | foreach (IFunction p in m_parameters.Parameters) 101 | { 102 | parameters.Add(p); 103 | } 104 | 105 | List saveParameters = new List(parameters.Select(p => p.Save(c))); 106 | 107 | if (m_paramFunction != null) 108 | { 109 | saveParameters.Add(string.Format("function (result) {{ {0} }}", m_paramFunction.Save(c))); 110 | } 111 | 112 | return SaveScript(m_procedure, saveParameters.ToArray()); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Utility/Utility.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {0E926905-F750-49F9-AEBD-CE14B2B231D8} 9 | Library 10 | Properties 11 | TextAdventures.Utility 12 | Utility 13 | v4.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\Debug\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | false 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | false 41 | 42 | 43 | true 44 | bin\x86\Debug\ 45 | DEBUG;TRACE 46 | full 47 | AnyCPU 48 | prompt 49 | false 50 | 51 | 52 | bin\x86\Release\ 53 | TRACE 54 | true 55 | pdbonly 56 | AnyCPU 57 | prompt 58 | false 59 | 60 | 61 | 62 | 63 | False 64 | ..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll 65 | 66 | 67 | 68 | 3.5 69 | 70 | 71 | 72 | 3.5 73 | 74 | 75 | 3.5 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 99 | -------------------------------------------------------------------------------- /QuestJSWeb/Scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); 18 | 19 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 20 | (function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); -------------------------------------------------------------------------------- /Compiler/Scripts/IfScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class IfScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "if"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string afterExpr; 18 | string expr = Utility.GetParameter(script, out afterExpr); 19 | string then = Utility.GetScript(afterExpr); 20 | 21 | IScript thenScript = ScriptFactory.CreateScript(then, proc); 22 | 23 | return new IfScript(new Expression(expr, GameLoader), thenScript); 24 | } 25 | 26 | public IScriptFactory ScriptFactory { get; set; } 27 | 28 | public GameLoader GameLoader { get; set; } 29 | 30 | public void AddElse(IScript script, string elseScript, Element proc) 31 | { 32 | IScript add = GetElse(elseScript, proc); 33 | ((IfScript)script).SetElse(add); 34 | } 35 | 36 | public void AddElseIf(IScript script, string elseIfScript, Element proc) 37 | { 38 | IScript add = GetElse(elseIfScript, proc); 39 | 40 | // GetElse uses the ScriptFactory to parse the "else if" block, so it will return 41 | // a MultiScript containing an IfScript with one expression and one "then" script block. 42 | 43 | IfScript elseIf = (IfScript)((MultiScript)add).Scripts.First(); 44 | 45 | ((IfScript)script).AddElseIf(elseIf.Expression, elseIf.ThenScript); 46 | } 47 | 48 | private IScript GetElse(string elseScript, Element proc) 49 | { 50 | elseScript = Utility.GetTextAfter(elseScript, "else"); 51 | return ScriptFactory.CreateScript(elseScript, proc); 52 | } 53 | } 54 | 55 | public class IfScript : ScriptBase 56 | { 57 | public class ElseIfScript 58 | { 59 | private IfScript m_parent; 60 | 61 | public ElseIfScript(IFunction expression, IScript script, IfScript parent, string id) 62 | { 63 | Expression = expression; 64 | Script = script; 65 | m_parent = parent; 66 | Id = id; 67 | } 68 | 69 | internal IFunction Expression { get; private set; } 70 | public IScript Script { get; private set; } 71 | public string Id { get; private set; } 72 | } 73 | 74 | private IFunction m_expression; 75 | private IScript m_thenScript; 76 | private IScript m_elseScript; 77 | private List m_elseIfScript = new List(); 78 | 79 | public IfScript(IFunction expression, IScript thenScript) 80 | : this(expression, thenScript, null) 81 | { 82 | } 83 | 84 | public IfScript(IFunction expression, IScript thenScript, IScript elseScript) 85 | { 86 | m_expression = expression; 87 | m_thenScript = thenScript; 88 | m_elseScript = elseScript; 89 | } 90 | 91 | public void SetElse(IScript elseScript) 92 | { 93 | m_elseScript = elseScript; 94 | } 95 | 96 | private int m_lastElseIfId = 0; 97 | 98 | private string GetNewElseIfID() 99 | { 100 | m_lastElseIfId++; 101 | return "elseif" + m_lastElseIfId; 102 | } 103 | 104 | public void AddElseIf(IFunction expression, IScript script) 105 | { 106 | ElseIfScript elseIfScript = new ElseIfScript(expression, script, this, GetNewElseIfID()); 107 | m_elseIfScript.Add(elseIfScript); 108 | } 109 | 110 | public override string Save(Context c) 111 | { 112 | string result = SaveExpressionScript("if", m_thenScript, c, m_expression.Save(c)); 113 | if (m_elseIfScript != null) 114 | { 115 | foreach (ElseIfScript elseIf in m_elseIfScript) 116 | { 117 | result += Environment.NewLine + SaveExpressionScript("else if", elseIf.Script, c, elseIf.Expression.Save(c)); 118 | } 119 | } 120 | if (m_elseScript != null) result += Environment.NewLine + "else {" + Environment.NewLine + m_elseScript.Save(c) + Environment.NewLine + "}"; 121 | return result; 122 | } 123 | 124 | internal IFunction Expression 125 | { 126 | get { return m_expression; } 127 | } 128 | 129 | public IScript ThenScript 130 | { 131 | get { return m_thenScript; } 132 | set { m_thenScript = value; } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Compiler/Scripts/SwitchScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class SwitchScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "switch"; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | string afterExpr; 18 | string param = Utility.GetParameter(script, out afterExpr); 19 | IScript defaultScript; 20 | var cases = ProcessCases(Utility.GetScript(afterExpr), out defaultScript, proc); 21 | 22 | return new SwitchScript(new Expression(param, GameLoader), cases, defaultScript); 23 | } 24 | 25 | public IScriptFactory ScriptFactory { get; set; } 26 | 27 | public GameLoader GameLoader { get; set; } 28 | 29 | private List, IScript>> ProcessCases(string cases, out IScript defaultScript, Element proc) 30 | { 31 | bool finished = false; 32 | string remainingCases; 33 | string afterExpr; 34 | var result = new List, IScript>>(); 35 | defaultScript = null; 36 | 37 | cases = Utility.RemoveSurroundingBraces(cases); 38 | 39 | while (!finished) 40 | { 41 | cases = Utility.GetScript(cases, out remainingCases); 42 | if (cases != null) cases = cases.Trim(); 43 | 44 | if (!string.IsNullOrEmpty(cases)) 45 | { 46 | if (cases.StartsWith("case")) 47 | { 48 | string expr = Utility.GetParameter(cases, out afterExpr); 49 | string caseScript = Utility.GetScript(afterExpr); 50 | IScript script = ScriptFactory.CreateScript(caseScript, proc); 51 | 52 | var matchList = Utility.SplitParameter(expr); 53 | var expressions = matchList.Select(match => new Expression(match, GameLoader)).Cast().ToList(); 54 | 55 | result.Add(Tuple.Create(expressions, script)); 56 | } 57 | else if (cases.StartsWith("default")) 58 | { 59 | defaultScript = ScriptFactory.CreateScript(cases.Substring(8).Trim()); 60 | } 61 | else 62 | { 63 | throw new Exception(string.Format("Invalid inside switch block: '{0}'", cases)); 64 | } 65 | } 66 | 67 | cases = remainingCases; 68 | if (string.IsNullOrEmpty(cases)) finished = true; 69 | } 70 | 71 | return result; 72 | } 73 | } 74 | 75 | public class SwitchScript : ScriptBase 76 | { 77 | private IFunction m_expr; 78 | private SwitchCases m_cases; 79 | private IScript m_default; 80 | 81 | public SwitchScript(IFunction expression, List, IScript>> cases, IScript defaultScript) 82 | : this(expression, defaultScript) 83 | { 84 | m_cases = new SwitchCases(this, cases); 85 | } 86 | 87 | private SwitchScript(IFunction expression, IScript defaultScript) 88 | { 89 | m_expr = expression; 90 | m_default = defaultScript ?? new MultiScript(); 91 | } 92 | 93 | public override string Save(Context c) 94 | { 95 | string result = string.Format("switch ({0}) {{\n", m_expr.Save(c)); 96 | result += m_cases.Save(c); 97 | if (m_default != null && ((MultiScript)m_default).Scripts.Count() > 0) result += "default:\n" + m_default.Save(c); 98 | result += Environment.NewLine + "}"; 99 | return result; 100 | } 101 | 102 | private class SwitchCases 103 | { 104 | private List, IScript>> m_cases; 105 | 106 | public SwitchCases(SwitchScript parent, List, IScript>> cases) 107 | { 108 | m_cases = cases; 109 | } 110 | 111 | public string Save(Context c) 112 | { 113 | string result = string.Empty; 114 | foreach (var caseItem in m_cases) 115 | { 116 | foreach (var expression in caseItem.Item1) 117 | { 118 | result += string.Format("case {0}:\n", expression.Save(c)); 119 | } 120 | result += string.Format("{0}\nbreak;\n", caseItem.Item2.Save(c)); 121 | } 122 | return result; 123 | } 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /Compiler/Element.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest 7 | { 8 | [AttributeUsage(AttributeTargets.Field)] 9 | public class ElementTypeInfo : Attribute 10 | { 11 | public ElementTypeInfo(string name) 12 | { 13 | Name = name; 14 | } 15 | public string Name; 16 | } 17 | 18 | public enum ElementType 19 | { 20 | [ElementTypeInfo("include")] 21 | IncludedLibrary, 22 | [ElementTypeInfo("implied")] 23 | ImpliedType, 24 | [ElementTypeInfo("template")] 25 | Template, 26 | [ElementTypeInfo("dynamictemplate")] 27 | DynamicTemplate, 28 | [ElementTypeInfo("delegate")] 29 | Delegate, 30 | [ElementTypeInfo("object")] 31 | Object, 32 | [ElementTypeInfo("type")] 33 | ObjectType, 34 | [ElementTypeInfo("function")] 35 | Function, 36 | [ElementTypeInfo("editor")] 37 | Editor, 38 | [ElementTypeInfo("tab")] 39 | EditorTab, 40 | [ElementTypeInfo("control")] 41 | EditorControl, 42 | [ElementTypeInfo("walkthrough")] 43 | Walkthrough, 44 | [ElementTypeInfo("javascript")] 45 | Javascript, 46 | [ElementTypeInfo("timer")] 47 | Timer, 48 | [ElementTypeInfo("resource")] 49 | Resource, 50 | } 51 | 52 | public enum ObjectType 53 | { 54 | Object, 55 | Exit, 56 | Command, 57 | Game, 58 | TurnScript 59 | } 60 | 61 | public class Element 62 | { 63 | private static Dictionary s_typeStrings; 64 | private static Dictionary s_mapObjectTypeStringsToElementType; 65 | private static Dictionary s_elemTypeStrings; 66 | private static Dictionary s_mapElemTypeStringsToElementType; 67 | 68 | static Element() 69 | { 70 | s_typeStrings = new Dictionary(); 71 | s_typeStrings.Add(ObjectType.Object, "object"); 72 | s_typeStrings.Add(ObjectType.Exit, "exit"); 73 | s_typeStrings.Add(ObjectType.Command, "command"); 74 | s_typeStrings.Add(ObjectType.Game, "game"); 75 | s_typeStrings.Add(ObjectType.TurnScript, "turnscript"); 76 | 77 | s_mapObjectTypeStringsToElementType = new Dictionary(); 78 | foreach (var item in s_typeStrings) 79 | { 80 | s_mapObjectTypeStringsToElementType.Add(item.Value, item.Key); 81 | } 82 | 83 | s_elemTypeStrings = new Dictionary(); 84 | foreach (ElementType t in Enum.GetValues(typeof(ElementType))) 85 | { 86 | s_elemTypeStrings.Add(t, ((ElementTypeInfo)(typeof(ElementType).GetField(t.ToString()).GetCustomAttributes(typeof(ElementTypeInfo), false)[0])).Name); 87 | } 88 | 89 | s_mapElemTypeStringsToElementType = new Dictionary(); 90 | foreach (var item in s_elemTypeStrings) 91 | { 92 | s_mapElemTypeStringsToElementType.Add(item.Value, item.Key); 93 | } 94 | } 95 | 96 | private ObjectType m_type; 97 | private ElementType m_elemType; 98 | private Fields m_fields = new Fields(); 99 | private Fields m_metaFields = new Fields(); 100 | private GameLoader m_loader; 101 | 102 | public Element(ElementType type, GameLoader loader) 103 | { 104 | ElemType = type; 105 | m_loader = loader; 106 | } 107 | 108 | public Element Parent 109 | { 110 | get { return Fields.GetAsType("parent"); } 111 | set { Fields.Set("parent", value); } 112 | } 113 | 114 | public string Name 115 | { 116 | get { return Fields.GetAsType("name"); } 117 | set { Fields.Set("name", value); } 118 | } 119 | 120 | public ObjectType Type 121 | { 122 | get 123 | { 124 | return m_type; 125 | } 126 | set 127 | { 128 | m_type = value; 129 | Fields.Set("type", TypeString); 130 | } 131 | } 132 | 133 | public ElementType ElemType 134 | { 135 | get 136 | { 137 | return m_elemType; 138 | } 139 | set 140 | { 141 | m_elemType = value; 142 | Fields.Set("elementtype", ElementTypeString); 143 | } 144 | } 145 | 146 | public Fields Fields { get { return m_fields; } } 147 | public Fields MetaFields { get { return m_metaFields; } } 148 | 149 | private string TypeString 150 | { 151 | get 152 | { 153 | return s_typeStrings[m_type]; 154 | } 155 | } 156 | 157 | private string ElementTypeString 158 | { 159 | get 160 | { 161 | return s_elemTypeStrings[m_elemType]; 162 | } 163 | } 164 | 165 | public GameLoader Loader { get { return m_loader; } } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /QuestCompiler/QuestCompiler.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {5A25FE48-0BE2-4B58-936C-3982B2EF8483} 9 | WinExe 10 | Properties 11 | QuestCompiler 12 | QuestCompiler 13 | v4.5 14 | 15 | 16 | 512 17 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 18 | 4 19 | 20 | 21 | x86 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | x86 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | false 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 4.0 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | 64 | MSBuild:Compile 65 | Designer 66 | 67 | 68 | App.xaml 69 | Code 70 | 71 | 72 | MainWindow.xaml 73 | Code 74 | 75 | 76 | 77 | 78 | Code 79 | 80 | 81 | True 82 | True 83 | Resources.resx 84 | 85 | 86 | True 87 | Settings.settings 88 | True 89 | 90 | 91 | ResXFileCodeGenerator 92 | Resources.Designer.cs 93 | 94 | 95 | 96 | SettingsSingleFileGenerator 97 | Settings.Designer.cs 98 | 99 | 100 | 101 | 102 | 103 | {64131651-5158-493D-A1CF-27C7575F2653} 104 | Compiler 105 | 106 | 107 | {0e926905-f750-49f9-aebd-ce14b2b231d8} 108 | Utility 109 | 110 | 111 | 112 | 113 | 114 | 115 | 122 | -------------------------------------------------------------------------------- /QuestJSWeb/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(c){var b=a(c),d=b.data(e),f=a.proxy(n,c);if(!d){d={options:{errorClass:"input-validation-error",errorElement:"span",errorPlacement:a.proxy(m,c),invalidHandler:a.proxy(l,c),messages:{},rules:{},success:a.proxy(k,c)},attachValidation:function(){b.unbind("reset."+e,f).bind("reset."+e,f).validate(this.options)},validate:function(){b.validate();return b.valid()}};b.data(e,d)}return d}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(b){var c=a(b).parents("form").andSelf().add(a(b).find("form")).filter("form");a(b).find(":input").filter("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});c.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input").filter("[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); 20 | -------------------------------------------------------------------------------- /Compiler/Scripts/SetScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class SetScriptConstructor : IScriptConstructor 9 | { 10 | public string Keyword 11 | { 12 | get { return "="; } 13 | } 14 | 15 | public IScript Create(string script, Element proc) 16 | { 17 | bool isScript = false; 18 | int offset = 0; 19 | int eqPos; 20 | 21 | // hide text within string expressions 22 | string obscuredScript = Utility.ObscureStrings(script); 23 | int bracePos = obscuredScript.IndexOf('{'); 24 | if (bracePos != -1) 25 | { 26 | // only want to look for = and => before any other scripts which may 27 | // be defined on the same line, for example procedure calls of type 28 | // MyProcedureCall (5) { some other script } 29 | 30 | obscuredScript = obscuredScript.Substring(0, bracePos); 31 | } 32 | 33 | eqPos = obscuredScript.IndexOf("=>"); 34 | if (eqPos != -1) 35 | { 36 | isScript = true; 37 | offset = 1; 38 | } 39 | else 40 | { 41 | eqPos = obscuredScript.IndexOf('='); 42 | } 43 | 44 | if (eqPos != -1) 45 | { 46 | string appliesTo = script.Substring(0, eqPos); 47 | string value = script.Substring(eqPos + 1 + offset).Trim(); 48 | 49 | string variable; 50 | IFunction expr = GetAppliesTo(appliesTo, out variable); 51 | 52 | if (!isScript) 53 | { 54 | return new SetExpressionScript(this, expr, variable, new Expression(value, GameLoader), GameLoader); 55 | } 56 | else 57 | { 58 | return new SetScriptScript(this, expr, variable, ScriptFactory.CreateScript(value), GameLoader); 59 | } 60 | } 61 | 62 | return null; 63 | } 64 | 65 | internal IFunction GetAppliesTo(string value, out string variable) 66 | { 67 | string var = value.Trim(); 68 | string obj; 69 | Utility.ResolveVariableName(ref var, out obj, out variable); 70 | return (obj == null) ? null : new Expression(obj, GameLoader); 71 | } 72 | 73 | public IScriptFactory ScriptFactory { get; set; } 74 | public GameLoader GameLoader { get; set; } 75 | } 76 | 77 | public abstract class SetScriptBase : ScriptBase 78 | { 79 | private IFunction m_appliesTo; 80 | private string m_property; 81 | private SetScriptConstructor m_constructor; 82 | private GameLoader m_loader; 83 | 84 | internal SetScriptBase(SetScriptConstructor constructor, IFunction appliesTo, string property, GameLoader loader) 85 | { 86 | m_constructor = constructor; 87 | AppliesTo = appliesTo; 88 | Property = property; 89 | m_loader = loader; 90 | } 91 | 92 | protected IFunction AppliesTo 93 | { 94 | get { return m_appliesTo; } 95 | private set 96 | { 97 | m_appliesTo = value; 98 | } 99 | } 100 | 101 | protected string Property 102 | { 103 | get { return m_property; } 104 | private set 105 | { 106 | m_property = value; 107 | } 108 | } 109 | 110 | public override string Save(Context c) 111 | { 112 | string result = string.Empty; 113 | 114 | if (AppliesTo != null) 115 | { 116 | result = string.Format("set({0}, \"{1}\", {2});", AppliesTo.Save(c), Property, GetSaveString(c)); 117 | } 118 | else 119 | { 120 | string varName = Utility.ReplaceReservedVariableNames(Property); 121 | result = "var " + varName; 122 | result += " = " + GetSaveString(c) + ";"; 123 | c.AddLocalVariable(varName); 124 | } 125 | 126 | return result; 127 | } 128 | 129 | protected abstract string GetSaveString(Context c); 130 | } 131 | 132 | public class SetExpressionScript : SetScriptBase 133 | { 134 | private Expression m_expr; 135 | 136 | public SetExpressionScript(SetScriptConstructor constructor, IFunction appliesTo, string property, Expression expr, GameLoader loader) 137 | : base(constructor, appliesTo, property, loader) 138 | { 139 | m_expr = expr; 140 | } 141 | 142 | protected override string GetSaveString(Context c) 143 | { 144 | return m_expr.Save(c); 145 | } 146 | } 147 | 148 | public class SetScriptScript : SetScriptBase 149 | { 150 | private IScript m_script; 151 | private IScriptFactory m_scriptFactory; 152 | 153 | public SetScriptScript(SetScriptConstructor constructor, IFunction appliesTo, string property, IScript script, GameLoader loader) 154 | : base(constructor, appliesTo, property, loader) 155 | { 156 | m_script = script; 157 | m_scriptFactory = constructor.ScriptFactory; 158 | } 159 | 160 | protected override string GetSaveString(Context c) 161 | { 162 | return string.Format("function() {{ {0} }}", m_script.Save(c)); 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Compiler/Scripts/CreateScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace TextAdventures.Quest.Scripts 7 | { 8 | public class CreateScriptConstructor : ScriptConstructorBase 9 | { 10 | public override string Keyword 11 | { 12 | get { return "create"; } 13 | } 14 | 15 | protected override IScript CreateInt(List parameters) 16 | { 17 | return new CreateScript(new Expression(parameters[0], GameLoader)); 18 | } 19 | 20 | protected override int[] ExpectedParameters 21 | { 22 | get { return new int[] { 1 }; } 23 | } 24 | } 25 | 26 | public class CreateScript : ScriptBase 27 | { 28 | private IFunction m_expr; 29 | 30 | public CreateScript(IFunction expr) 31 | { 32 | m_expr = expr; 33 | } 34 | 35 | public override string Save(Context c) 36 | { 37 | return SaveScript("create", m_expr.Save(c)); 38 | } 39 | } 40 | 41 | public class CreateExitScriptConstructor : ScriptConstructorBase 42 | { 43 | public override string Keyword 44 | { 45 | get { return "create exit"; } 46 | } 47 | 48 | protected override IScript CreateInt(List parameters) 49 | { 50 | switch (parameters.Count) 51 | { 52 | case 3: 53 | return new CreateExitScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader)); 54 | case 4: 55 | return new CreateExitScript(new Expression(parameters[0], GameLoader), new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader), new Expression(parameters[3], GameLoader)); 56 | case 5: 57 | return new CreateExitScript(new Expression(parameters[1], GameLoader), new Expression(parameters[2], GameLoader), new Expression(parameters[3], GameLoader), new Expression(parameters[4], GameLoader), new Expression(parameters[0], GameLoader)); 58 | } 59 | return null; 60 | } 61 | 62 | protected override int[] ExpectedParameters 63 | { 64 | get { return new int[] { 3, 4, 5 }; } 65 | } 66 | } 67 | 68 | public class CreateExitScript : ScriptBase 69 | { 70 | private IFunction m_name; 71 | private IFunction m_from; 72 | private IFunction m_to; 73 | private IFunction m_initialType; 74 | private IFunction m_id; 75 | 76 | public CreateExitScript(IFunction name, IFunction from, IFunction to) 77 | { 78 | m_name = name; 79 | m_from = from; 80 | m_to = to; 81 | } 82 | 83 | public CreateExitScript(IFunction name, IFunction from, IFunction to, IFunction initialType) 84 | : this(name, from, to) 85 | { 86 | m_initialType = initialType; 87 | } 88 | 89 | public CreateExitScript(IFunction name, IFunction from, IFunction to, IFunction initialType, IFunction id) 90 | : this(name, from, to, initialType) 91 | { 92 | m_id = id; 93 | } 94 | 95 | public override string Save(Context c) 96 | { 97 | if (m_initialType == null) 98 | { 99 | return SaveScript("createexit", m_name.Save(c), m_from.Save(c), m_to.Save(c)); 100 | } 101 | else 102 | { 103 | // TODO: Add support for id parameter 104 | return SaveScript("createexit_withtype", m_name.Save(c), m_from.Save(c), m_to.Save(c), m_initialType.Save(c)); 105 | } 106 | } 107 | } 108 | 109 | public class CreateTimerScriptConstructor : ScriptConstructorBase 110 | { 111 | public override string Keyword 112 | { 113 | get { return "create timer"; } 114 | } 115 | 116 | protected override IScript CreateInt(List parameters) 117 | { 118 | return new CreateTimerScript(new Expression(parameters[0], GameLoader)); 119 | } 120 | 121 | protected override int[] ExpectedParameters 122 | { 123 | get { return new int[] { 1 }; } 124 | } 125 | } 126 | 127 | public class CreateTimerScript : ScriptBase 128 | { 129 | private IFunction m_expr; 130 | 131 | public CreateTimerScript(IFunction expr) 132 | { 133 | m_expr = expr; 134 | } 135 | 136 | public override string Save(Context c) 137 | { 138 | return SaveScript("createtimer", m_expr.Save(c)); 139 | } 140 | } 141 | 142 | public class CreateTurnScriptConstructor : ScriptConstructorBase 143 | { 144 | public override string Keyword 145 | { 146 | get { return "create turnscript"; } 147 | } 148 | 149 | protected override IScript CreateInt(List parameters) 150 | { 151 | return new CreateTurnScript(new Expression(parameters[0], GameLoader)); 152 | } 153 | 154 | protected override int[] ExpectedParameters 155 | { 156 | get { return new int[] { 1 }; } 157 | } 158 | } 159 | 160 | public class CreateTurnScript : ScriptBase 161 | { 162 | private IFunction m_expr; 163 | 164 | public CreateTurnScript(IFunction expr) 165 | { 166 | m_expr = expr; 167 | } 168 | 169 | public override string Save(Context c) 170 | { 171 | return SaveScript("createturnscript", m_expr.Save(c)); 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /Compiler/GameSaver/ElementSavers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using TextAdventures.Quest.Scripts; 6 | 7 | namespace TextAdventures.Quest 8 | { 9 | internal abstract class ElementSaverBase 10 | { 11 | FieldSaver fieldSaver = new FieldSaver(); 12 | 13 | protected void SaveElementFields(string name, Element e, GameWriter writer) 14 | { 15 | string mappedName = e.MetaFields[MetaFieldDefinitions.MappedName]; 16 | 17 | writer.AddLine(mappedName + " = {"); 18 | e.Fields.Set("_js_name", mappedName); 19 | e.Fields.Set("_types", new QuestList(e.Fields.TypeNames)); 20 | 21 | int count = 0; 22 | int length = e.Fields.FieldNames.Count(); 23 | 24 | foreach (string field in e.Fields.FieldNames) 25 | { 26 | count++; 27 | object value = ConvertField(e, field, e.Fields.Get(field)); 28 | fieldSaver.Save(writer, e, field, value, count == length); 29 | } 30 | 31 | writer.AddLine("};"); 32 | writer.AddLine(string.Format("elementsNameMap[\"{0}\"] = {1};", e.Name, e.MetaFields[MetaFieldDefinitions.MappedName])); 33 | writer.MarkElementWritten(e); 34 | } 35 | 36 | protected virtual object ConvertField(Element e, string fieldName, object value) 37 | { 38 | return value; 39 | } 40 | } 41 | 42 | internal abstract class ObjectSaverBase : ElementSaverBase 43 | { 44 | private Dictionary allObjectsArray = new Dictionary { 45 | { ObjectType.Object, "allObjects" }, 46 | { ObjectType.Command, "allCommands" }, 47 | { ObjectType.Exit, "allExits" }, 48 | { ObjectType.TurnScript, "allTurnScripts" } 49 | }; 50 | 51 | public void Save(Element e, GameWriter writer) 52 | { 53 | base.SaveElementFields(e.Name, e, writer); 54 | string postElementScript = writer.GetPostElementScript(e); 55 | if (postElementScript.Length > 0) writer.AddLine(postElementScript); 56 | if (allObjectsArray.ContainsKey(e.Type)) 57 | { 58 | writer.AddLine(string.Format("{0}.push({1});", allObjectsArray[e.Type], e.MetaFields[MetaFieldDefinitions.MappedName])); 59 | } 60 | writer.AddLine(string.Format("objectsNameMap[\"{0}\"] = {1};", e.Name, e.MetaFields[MetaFieldDefinitions.MappedName])); 61 | } 62 | } 63 | 64 | internal class ObjectSaver : ObjectSaverBase, IElementSaver 65 | { 66 | public ElementType AppliesTo 67 | { 68 | get { return ElementType.Object; } 69 | } 70 | } 71 | 72 | internal class TemplateSaver : IElementSaver 73 | { 74 | public ElementType AppliesTo 75 | { 76 | get { return ElementType.Template; } 77 | } 78 | 79 | public void Save(Element e, GameWriter writer) 80 | { 81 | if (e.Fields[FieldDefinitions.TemplateName] == "EditorVerbDefaultExpression") return; 82 | writer.AddLine(string.Format("templates.t_{0} = \"{1}\"", e.Fields[FieldDefinitions.TemplateName], e.Fields[FieldDefinitions.Text].Replace("\n", "").Replace("\r", ""))); 83 | } 84 | } 85 | 86 | internal class DynamicTemplateSaver : IElementSaver 87 | { 88 | public ElementType AppliesTo 89 | { 90 | get { return ElementType.DynamicTemplate; } 91 | } 92 | 93 | public void Save(Element e, GameWriter writer) 94 | { 95 | string expression = e.Fields[FieldDefinitions.Function].Save(new Context()); 96 | expression = Utility.ReplaceDynamicTemplateVariableNames(expression); 97 | writer.AddLine(string.Format("dynamicTemplates.{0} = function(params) {{ return {1}; }};", e.Name, expression)); 98 | } 99 | } 100 | 101 | internal class DelegateSaver : IElementSaver 102 | { 103 | public ElementType AppliesTo 104 | { 105 | get { return ElementType.Delegate; } 106 | } 107 | 108 | public void Save(Element e, GameWriter writer) 109 | { 110 | // Delegate definitions don't need saving in Javascript 111 | } 112 | } 113 | 114 | internal class ObjectTypeSaver : ObjectSaverBase, IElementSaver 115 | { 116 | // TO DO: This will simply save the type - we need more logic to actually include the type in objects that inherit it 117 | 118 | public ElementType AppliesTo 119 | { 120 | get { return ElementType.ObjectType; } 121 | } 122 | } 123 | 124 | internal class JavacriptSaver : IElementSaver 125 | { 126 | public ElementType AppliesTo 127 | { 128 | get { return ElementType.Javascript; } 129 | } 130 | 131 | public void Save(Element e, GameWriter writer) 132 | { 133 | // Do nothing, .js files will be picked up from the resources folder and embedded in game.js automatically 134 | } 135 | } 136 | 137 | internal class TimerSaver : ElementSaverBase, IElementSaver 138 | { 139 | public ElementType AppliesTo 140 | { 141 | get { return ElementType.Timer; } 142 | } 143 | 144 | public void Save(Element e, GameWriter writer) 145 | { 146 | base.SaveElementFields(e.Name, e, writer); 147 | writer.AddLine(string.Format("allTimers.push({0});", e.MetaFields[MetaFieldDefinitions.MappedName])); 148 | writer.AddLine(string.Format("objectsNameMap[\"{0}\"] = {1};", e.Name, e.MetaFields[MetaFieldDefinitions.MappedName])); 149 | } 150 | } 151 | } 152 | --------------------------------------------------------------------------------