private void ExportGlobalScripts() { SPAGS.ScriptCollection scripts = new SPAGS.ScriptCollection(editor.Version); scripts.SetStandardConstants(editor.CurrentGame.Settings); scripts.AddStandardHeaders(editor); List<SPAGS.Script> globalScripts = GetGlobalScripts(scripts); JS.SPAGSConverter convert = new JS.SPAGSConverter(); JS.Script script = new JS.Script(); JS.Expression ags = script.GetExternalGlobal("ags"); JS.Expression jQuery = script.GetExternalGlobal("jQuery"); JS.Expression ags_util = ags.Index("util"); JS.Expression ags_games_guid = ags.Index("games", GetCurrentGameGuid()); JS.FunctionDefinition initFunc = new JS.FunctionDefinition(); { JS.Variable initializerParam_jQuery = initFunc.NewParam("$"); JS.FunctionDefinition ctor = new JS.FunctionDefinition(); JS.Expression.ObjectLiteral ctorProto = new JS.Expression.ObjectLiteral(); { JS.Variable ctorParam_engine = ctor.NewParam("engine"); JS.Variable ctorParam_game = ctor.NewParam("game"); JS.Variable ctorVar_util = ctor.NewVar("util"); ctorVar_util.InitialValue = ags_util; JS.Variable ctorVar_self = ctor.NewVar("globalScripts"); ctorVar_self.InitialValue = ctor.This; foreach (SPAGS.Function globalFunc in scripts.GlobalNamespace.EachOf<SPAGS.Function>()) { if (globalFunc.OwnerScript == null) { JS.Expression specialExpr; if (convert.GetSpecial(globalFunc, out specialExpr)) { convert.AddReference(globalFunc, specialExpr); } else { string funcName = globalFunc.Name.Replace("::", "$$"); convert.AddReference(globalFunc, ctorParam_engine.Index(funcName)); } } } foreach (SPAGS.Variable globalVar in scripts.GlobalNamespace.EachOf<SPAGS.Variable>()) { if (globalVar.OwnerScript == null) { convert.AddReference(globalVar, ctorParam_game.Index(globalVar.Name, convert.GetValueTypes(globalVar.Type))); } } Dictionary<SPAGS.Function, JS.FunctionDefinition> funcDefs = new Dictionary<SPAGS.Function, JS.FunctionDefinition>(); foreach (SPAGS.Script globalScript in globalScripts) { string scriptName = Regex.Replace(globalScript.Name, @"\..*$", ""); scriptName = Regex.Replace(scriptName, "[^a-zA-Z_0-9]", "_"); if (!Regex.IsMatch(scriptName, "^[a-zA-Z_]")) { if (globalScript.Name.EndsWith(".ash")) { scriptName = "h$" + scriptName; } else { scriptName = "s$" + scriptName; } } foreach (SPAGS.ValueType.Struct structType in globalScript.DefinedStructs) { if (structType.IsManaged) { continue; } string structName = scriptName + "$" + structType.Name; JS.Variable structVar = ctor.NewVar(structName); convert.AddReference(structType, structVar); JS.FunctionDefinition structCtor = new JS.FunctionDefinition(); ctor.Body.Add(structVar.Assign(structCtor)); JS.Expression.ObjectLiteral structProto = new JS.Expression.ObjectLiteral(); foreach (SPAGS.StructMember.Field field in structType.Members.EachOf<SPAGS.StructMember.Field>()) { SPAGS.Expression initValue = field.Type.CreateDefaultValueExpression(); if (initValue.IsConstant()) { structProto.Add(field.Name, convert.FromSPAGS(initValue)); } else { structProto.Add(field.Name, JS.Expression.Null); structCtor.Body.Add(structCtor.This.Index(field.Name).Assign(convert.FromSPAGS(initValue))); } } if (structProto.Entries.Count > 0) { ctor.Body.Add(structVar.Index("prototype").Assign(structProto)); } if (scripts.GlobalNamespace.ContainsKey(structType.Name) && scripts.GlobalNamespace[structType.Name] == structType) { ctor.Body.Add(ctorVar_self.Index(structType.Name).Assign(structVar)); } } foreach (SPAGS.Variable spagsVar in globalScript.DefinedVariables) { JS.Expression jsVar; if (scripts.GlobalNamespace.ContainsKey(spagsVar.Name) && scripts.GlobalNamespace[spagsVar.Name] == spagsVar) { jsVar = ctorVar_self.Index(spagsVar.Name, convert.GetValueTypes(spagsVar.Type)); SPAGS.Expression value = spagsVar.InitialValue ?? spagsVar.Type.CreateDefaultValueExpression(); if (value.IsConstant()) { ctorProto.Entries.Add(spagsVar.Name, convert.FromSPAGS(value)); } else { ctor.Body.Add(jsVar.Assign(convert.FromSPAGS(value))); } } else { string varName = scriptName + "$" + spagsVar.Name; jsVar = ctor.NewVar(varName, convert.GetValueTypes(spagsVar.Type)); if (spagsVar.InitialValue == null) { ctor.Body.Add(jsVar.Assign(convert.FromSPAGS(spagsVar.Type.CreateDefaultValueExpression()))); } else { ctor.Body.Add(jsVar.Assign(convert.FromSPAGS(spagsVar.InitialValue))); } } convert.AddReference(spagsVar, jsVar); } foreach (SPAGS.Function scriptFunc in globalScript.DefinedFunctions) { string funcName = scriptName + "$" + scriptFunc.Name.Replace("::", "$$"); JS.Variable funcVar = ctor.NewVar(funcName); JS.FunctionDefinition funcDef = new JS.FunctionDefinition(); convert.AddReference(scriptFunc, funcVar); funcDefs.Add(scriptFunc, funcDef); ctor.Body.Add(funcVar.Assign(funcDef)); foreach (SPAGS.Parameter param in scriptFunc.ParameterVariables) { string paramName = "p$" + param.Name; JS.Variable jsParam = funcDef.NewParam(paramName); jsParam.VariableType = convert.GetValueTypes(param.Type); convert.AddReference(param, jsParam); } ctor.Body.Add(ctorVar_self.Index(scriptFunc.Name.Replace("::","$$")).Assign(funcVar)); } } // process function bodies separately foreach (SPAGS.Script globalScript in globalScripts) { foreach (SPAGS.Function scriptFunc in globalScript.DefinedFunctions) { JS.FunctionDefinition funcDef = funcDefs[scriptFunc]; funcDef.Body = convert.FunctionBodyFromSPAGS(scriptFunc); } } } initFunc.Body.Add(ags_games_guid.Index("GlobalScripts").Assign(ctor)); if (ctorProto.Entries.Count > 0) { initFunc.Body.Add(ags_games_guid.Index("GlobalScripts", "prototype").Assign(ctorProto)); } } script.Add((JS.Statement)jQuery.Call(initFunc)); Dictionary<SPAGS.Function, bool> blockingFunctions = new Dictionary<SPAGS.Function,bool>(); foreach (SPAGS.Function func in scripts.GlobalNamespace.EachOf<SPAGS.Function>()) { switch (func.Name) { case "Game::InputBox": case "Display": case "DisplayAt": case "DisplayMessage": case "DisplayMessageAtY": case "DisplayTopBar": case "DisplayMessageBar": case "ProcessClick": case "QuitGame": case "AbortGame": case "RestartGame": case "InputBox": case "InventoryScreen": case "RunObjectInteraction": case "AnimateObject": case "AnimateObjectEx": case "MoveObject": case "MoveObjectDirect": case "RunCharacterInteraction": case "DisplaySpeech": case "DisplayThought": case "AnimateCharacter": case "AnimateCharacterEx": case "MoveCharacter": case "MoveCharacterDirect": case "MoveCharacterPath": case "MoveCharacterStraight": case "MoveCharacterToHotspot": case "MoveCharacterToObject": case "MoveCharacterBlocking": case "FaceCharacter": case "FaceLocation": case "RunHotspotInteraction": case "RunRegionInteraction": case "RunInventoryInteraction": case "InventoryItem::RunInteraction": case "FadeIn": case "FadeOut": case "ShakeScreen": case "PlayFlic": case "PlayVideo": case "Wait": case "WaitKey": case "WaitMouseKey": case "Hotspot::RunInteraction": case "Region::RunInteraction": case "Dialog::DisplayOptions": case "Object::Animate": case "Object::Move": case "Object::RunInteraction": case "Character::Animate": case "Character::FaceCharacter": case "Character::FaceLocation": case "Character::FaceObject": case "Character::Move": case "Character::RunInteraction": case "Character::Say": case "Character::SayAt": case "Character::Think": case "Character::Walk": case "Character::WalkStraight": func.AddSelfAndAllCallersTo(blockingFunctions); break; } } using (JS.Writer output = JS.Writer.Create(InExportFolder(GLOBAL_SCRIPTS_FILENAME))) { foreach (SPAGS.Function func in scripts.Exported.EachOf<SPAGS.Function>()) { if (func.Body == null || !blockingFunctions.ContainsKey(func)) continue; SPAGS.SimSynch.SimSynchFunction ssf = SPAGS.SimSynch.SimSynchFunction.Create(func, blockingFunctions); output.WriteLine(ssf.ToString()); } script.WriteTo(output); } }
private void ExportCurrentRoomScript() { SPAGS.ScriptCollection scripts = new SPAGS.ScriptCollection(editor.Version); scripts.SetStandardConstants(editor.CurrentGame.Settings); scripts.AddStandardHeaders(editor); List<SPAGS.Script> globalScripts = GetGlobalScripts(scripts); SPAGS.ValueType.Struct hotspotType, objectType; if (!scripts.GlobalNamespace.TryGetValue2<SPAGS.ValueType.Struct>("Hotspot", out hotspotType)) { throw new Exception("Unable to find \"Hotspot\" type!"); } if (!scripts.GlobalNamespace.TryGetValue2<SPAGS.ValueType.Struct>("Object", out objectType)) { throw new Exception("Unable to find \"Object\" type!"); } StringBuilder roomHeaderSB = new StringBuilder(); foreach (AGS.Types.RoomHotspot hs in editor.RoomController.CurrentRoom.Hotspots) { roomHeaderSB.AppendLine("Hotspot " + hs.Name + ";"); } foreach (AGS.Types.RoomObject obj in editor.RoomController.CurrentRoom.Objects) { roomHeaderSB.AppendLine("Object " + obj.Name + ";"); } SPAGS.Script roomHeader = scripts.AddHeader("___CurrentRoomScript__.ash", roomHeaderSB.ToString()); SPAGS.Script roomScript = null; foreach (AGS.Types.IRoom iroom in editor.CurrentGame.Rooms) { if (iroom.Number == editor.RoomController.CurrentRoom.Number) { roomScript = scripts.CompileScript("___CurrentRoomScript__.asc", iroom.Script.Text); } } if (roomScript == null) { throw new Exception("Room #" + editor.RoomController.CurrentRoom.Number + " not found!"); } JS.SPAGSConverter convert = new JS.SPAGSConverter(); JS.Script script = new JS.Script(); JS.Expression ags = script.GetExternalGlobal("ags"); JS.Expression jQuery = script.GetExternalGlobal("jQuery"); JS.Expression ags_util = ags.Index("util"); JS.Expression ags_games_guid = ags.Index("games", GetCurrentGameGuid()); JS.FunctionDefinition initFunc = new JS.FunctionDefinition(); { JS.Variable initializerParam_jQuery = initFunc.NewParam("$"); JS.FunctionDefinition ctor = new JS.FunctionDefinition(); JS.Expression.ObjectLiteral ctorProto = new JS.Expression.ObjectLiteral(); { JS.Variable ctorParam_engine = ctor.NewParam("engine"); JS.Variable ctorParam_game = ctor.NewParam("game"); JS.Variable ctorParam_room = ctor.NewParam("room"); JS.Variable ctorVar_util = ctor.NewVar("util"); ctorVar_util.InitialValue = ags_util; JS.Variable ctorVar_self = ctor.NewVar("roomScript"); ctorVar_self.InitialValue = ctor.This; JS.Variable ctorVar_globalScripts = ctor.NewVar("globalScripts"); ctorVar_globalScripts.InitialValue = ctorParam_game.Index("globalScripts"); foreach (SPAGS.Function globalFunc in scripts.GlobalNamespace.EachOf<SPAGS.Function>()) { if (globalFunc.OwnerScript == null) { JS.Expression specialExpr; if (convert.GetSpecial(globalFunc, out specialExpr)) { convert.AddReference(globalFunc, specialExpr); } else { string funcName = globalFunc.Name.Replace("::", "$$"); convert.AddReference(globalFunc, ctorParam_engine.Index(funcName)); } } } foreach (SPAGS.Function exportedFunc in scripts.Exported.EachOf<SPAGS.Function>()) { if (exportedFunc.OwnerScript != null && exportedFunc.OwnerScript != roomScript) { convert.AddReference(exportedFunc, ctorVar_globalScripts.Index(exportedFunc.Name.Replace("::", "$$"))); } } foreach (SPAGS.Variable globalVar in scripts.GlobalNamespace.EachOf<SPAGS.Variable>()) { if (globalVar.OwnerScript == null) { convert.AddReference(globalVar, ctorParam_game.Index(globalVar.Name, convert.GetValueTypes(globalVar.Type))); } else { if (globalVar.OwnerScript == roomHeader) { convert.AddReference(globalVar, ctorParam_room.Index(globalVar.Name, convert.GetValueTypes(globalVar.Type))); } else { convert.AddReference(globalVar, ctorVar_globalScripts.Index(globalVar.Name, convert.GetValueTypes(globalVar.Type))); } } } foreach (SPAGS.ValueType.Struct structType in roomScript.DefinedStructs) { if (structType.IsManaged) { continue; } string structName = "t$" + structType.Name; JS.Variable structVar = ctor.NewVar(structName); convert.AddReference(structType, structVar); JS.FunctionDefinition structCtor = new JS.FunctionDefinition(); ctor.Body.Add(structVar.Assign(structCtor)); JS.Expression.ObjectLiteral structProto = new JS.Expression.ObjectLiteral(); foreach (SPAGS.StructMember.Field field in structType.Members.EachOf<SPAGS.StructMember.Field>()) { SPAGS.Expression initValue = field.Type.CreateDefaultValueExpression(); if (initValue.IsConstant()) { structProto.Add(field.Name, convert.FromSPAGS(initValue)); } else { structProto.Add(field.Name, JS.Expression.Null); structCtor.Body.Add(structCtor.This.Index(field.Name).Assign(convert.FromSPAGS(initValue))); } } if (structProto.Entries.Count > 0) { ctor.Body.Add(structVar.Index("prototype").Assign(structProto)); } if (scripts.GlobalNamespace.ContainsKey(structType.Name) && scripts.GlobalNamespace[structType.Name] == structType) { ctor.Body.Add(ctorVar_self.Index(structType.Name).Assign(structVar)); } } foreach (SPAGS.Variable roomVar in roomScript.DefinedVariables) { string varName = "v$" + roomVar.Name; JS.Variable jsVar = ctor.NewVar(varName, convert.GetValueTypes(roomVar.Type)); convert.AddReference(roomVar, jsVar); SPAGS.Expression value = roomVar.InitialValue ?? roomVar.Type.CreateDefaultValueExpression(); if (value.IsConstant()) { jsVar.InitialValue = convert.FromSPAGS(value); } else { ctor.Body.Add(jsVar.Assign(convert.FromSPAGS(value))); } } Dictionary<SPAGS.Function, JS.FunctionDefinition> funcDefs = new Dictionary<SPAGS.Function, JS.FunctionDefinition>(); foreach (SPAGS.Function func in roomScript.DefinedFunctions) { string funcName = "f$" + func.Name.Replace("::","$$"); JS.Variable funcVar = ctor.NewVar(funcName); JS.FunctionDefinition funcDef = new JS.FunctionDefinition(); foreach (SPAGS.Parameter spagsParam in func.ParameterVariables) { string paramName = "p$" + spagsParam.Name; JS.Variable jsParam = funcDef.NewParam(paramName); jsParam.VariableType = convert.GetValueTypes(spagsParam.Type); convert.SetReference(spagsParam, jsParam); } funcDefs[func] = funcDef; ctor.Body.Add(funcVar.Assign(funcDef)); ctor.Body.Add(ctorVar_self.Index(func.Name).Assign(funcVar)); convert.AddReference(func, funcVar); } foreach (SPAGS.Function func in roomScript.DefinedFunctions) { JS.FunctionDefinition funcDef = funcDefs[func]; funcDef.Body = convert.FunctionBodyFromSPAGS(func); } } initFunc.Body.Add(ags_games_guid.Index("Room" + editor.RoomController.CurrentRoom.Number + "Script").Assign(ctor)); if (ctorProto.Entries.Count > 0) { initFunc.Body.Add(ags_games_guid.Index("Room" + editor.RoomController.CurrentRoom.Number + "Script", "prototype").Assign(ctorProto)); } } script.Add((JS.Statement)jQuery.Call(initFunc)); using (JS.Writer output = JS.Writer.Create(InExportFolder(ROOM_SCRIPT_FILENAME, editor.RoomController.CurrentRoom.Number))) { script.WriteTo(output); } }