/// <summary> /// 构造器 /// </summary> /// <param name="scenario">场景名称</param> /// <param name="mainSa">构造序列</param> /// <param name="funcVec">函数向量</param> public Scene(string scenario, SceneAction mainSa, List<SceneFunction> funcVec, Dictionary<string, SceneAction> labelDict) { this.Scenario = scenario; this.Ctor = mainSa; this.FuncContainer = funcVec; this.LabelDictionary = labelDict; }
/// <summary> /// 构造器 /// </summary> public SceneFunction(string callname, string parent, SceneAction sa = null) { this.ParentSceneName = parent; this.Callname = callname; this.Sa = sa; }
/// <summary> /// 将IL解析为SAP /// </summary> private void ProcessIL() { this.ilPackageContainer = new Dictionary<string, Dictionary<string, SceneActionPackage>>(); this.iResContainer = new Dictionary<string, Dictionary<string, SceneAction>>(); string currentSceneKey = ""; foreach (string lineitem in this.splitContianer) { // 处理头部 if (lineitem.StartsWith(">>>")) { string mycommand = lineitem.Substring(3).Replace("\r\n", ""); // EOF标记 if (mycommand == "YuriEOF") { break; } // 场景标记 if (mycommand.StartsWith("YuriIL?")) { string[] commandItem = mycommand.Split('?'); currentSceneKey = commandItem[1]; this.ilPackageContainer.Add(currentSceneKey, new Dictionary<string,SceneActionPackage>()); this.iResContainer.Add(currentSceneKey, new Dictionary<string,SceneAction>()); } else if (mycommand.StartsWith("YuriAEIL")) { string[] commandItem = mycommand.Split('?'); GlobalDataContainer.GAME_PROJECT_NAME = commandItem[1]; GlobalDataContainer.GAME_TITLE_NAME = commandItem[1]; } } else { // sap SceneActionPackage sap = this.ParseSceneActionPackage(lineitem); this.ilPackageContainer[currentSceneKey].Add(sap.saNodeName, sap); // sa SceneAction sa = new SceneAction(sap); this.iResContainer[currentSceneKey].Add(sa.saNodeName, sa); } } CommonUtils.ConsoleLine(String.Format("Finished Convert IL to SAP"), "YuriIL Convertor", OutputStyle.Normal); }
/// <summary> /// 将动作序列绑定到一个新的场景函数 /// </summary> /// <param name="funcSa">动作序列</param> /// <param name="sceneName">场景名称</param> /// <returns>场景函数</returns> private SceneFunction ParseSaToSF(SceneAction funcSa, string sceneName) { // 获得函数签名 string signature = funcSa.argsDict["sign"]; string[] signItem = signature.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries); List<string> funcParas = new List<string>(); // 如果没有参数就跳过参数遍历 if (signItem.Length > 1) { string[] varItem = signItem[1].Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string ivar in varItem) { funcParas.Add(ivar); } } SceneFunction nsf = new SceneFunction(signItem[0].Trim(), sceneName, funcSa); nsf.Param = funcParas; return nsf; }
/// <summary> /// 为当前动作创建一个副本 /// </summary> /// <param name="pureClone">是否保留关系</param> /// <returns>原动作的深拷贝副本</returns> public SceneAction Clone(bool pureClone) { SceneAction resSa = new SceneAction(); resSa.argsDict = new Dictionary<string, string>(); foreach (var kv in this.argsDict) { resSa.argsDict.Add(kv.Key, kv.Value); } resSa.aTag = this.aTag; resSa.aType = this.aType; resSa.funcName = this.funcName; resSa.isBelongFunc = this.isBelongFunc; resSa.saNodeName = this.saNodeName; if (pureClone == false) { resSa.condPolish = this.condPolish; resSa.next = this.next; resSa.saNodeName = this.saNodeName; resSa.trueRouting = new List<SceneAction>(); foreach (var tr in this.trueRouting) { resSa.trueRouting.Add(tr); } resSa.falseRouting = new List<SceneAction>(); foreach (var fr in this.falseRouting) { resSa.falseRouting.Add(fr); } } return resSa; }
/// <summary> /// 演绎函数:中断循环 /// </summary> /// <param name="breakSa">中断循环动作实例</param> private void Break(SceneAction breakSa) { Director.RunMana.CallStack.ESP.IP = breakSa.next; }
/// <summary> /// 接受一个场景动作并演绎她 /// </summary> /// <param name="action">场景动作实例</param> public void Accept(SceneAction action) { switch (action.aType) { case SActionType.act_a: this.A( this.ParseDirectString(action.argsDict["name"], ""), this.ParseInt(action.argsDict["vid"], -1), this.ParseDirectString(action.argsDict["face"], ""), this.ParseDirectString(action.argsDict["loc"], "") ); break; case SActionType.act_bg: this.Background( this.ParseInt(action.argsDict["id"], 0), this.ParseDirectString(action.argsDict["filename"], ""), this.ParseDouble(action.argsDict["x"], 0), this.ParseDouble(action.argsDict["y"], 0), this.ParseDouble(action.argsDict["opacity"], 1), this.ParseDouble(action.argsDict["xscale"], 1), this.ParseDouble(action.argsDict["yscale"], 1), this.ParseDouble(action.argsDict["ro"], 0), SpriteAnchorType.Center, new Int32Rect(-1, 0, 0, 0) ); break; case SActionType.act_picture: this.Picture( this.ParseInt(action.argsDict["id"], 0), this.ParseDirectString(action.argsDict["filename"], ""), this.ParseDouble(action.argsDict["x"], 0), this.ParseDouble(action.argsDict["y"], 0), this.ParseDouble(action.argsDict["opacity"], 1), this.ParseDouble(action.argsDict["xscale"], 1), this.ParseDouble(action.argsDict["yscale"], 1), this.ParseDouble(action.argsDict["ro"], 0), SpriteAnchorType.Center, new Int32Rect(-1, 0, 0, 0) ); break; case SActionType.act_move: string moveResType = action.argsDict["name"]; this.Move( this.ParseInt(action.argsDict["id"], 0), moveResType == "picture" ? ResourceType.Pictures : (moveResType == "stand" ? ResourceType.Stand : ResourceType.Background), this.ParseDirectString(action.argsDict["target"], ""), this.ParseDouble(action.argsDict["dash"], 1), this.ParseDouble(action.argsDict["acc"], 0), TimeSpan.FromMilliseconds(this.ParseDouble(action.argsDict["time"], 0)) ); break; case SActionType.act_deletepicture: this.Deletepicture( this.ParseInt(action.argsDict["id"], -1), ResourceType.Pictures ); break; case SActionType.act_cstand: this.Cstand( this.ParseInt(action.argsDict["id"], 0), String.Format("{0}_{1}.png", action.argsDict["name"], action.argsDict["face"]), this.ParseDouble(action.argsDict["x"], 0), this.ParseDouble(action.argsDict["y"], 0), this.ParseDouble(action.argsDict["opacity"], 1), this.ParseDouble(action.argsDict["xscale"], 1), this.ParseDouble(action.argsDict["yscale"], 1), this.ParseDouble(action.argsDict["ro"], 0), action.argsDict["anchor"] == "" ? (action.argsDict["anchor"] == "center" ? SpriteAnchorType.Center : SpriteAnchorType.LeftTop) : SpriteAnchorType.Center, new Int32Rect(0, 0, 0, 0) ); break; case SActionType.act_deletecstand: this.Deletecstand( (CharacterStandType)this.ParseInt(action.argsDict["id"], 5) ); break; case SActionType.act_se: this.Se( this.ParseDirectString(action.argsDict["filename"], ""), this.ParseDouble(action.argsDict["vol"], 1000) ); break; case SActionType.act_bgm: this.Bgm( this.ParseDirectString(action.argsDict["filename"], ""), this.ParseDouble(action.argsDict["vol"], 1000) ); break; case SActionType.act_stopbgm: this.Stopbgm(); break; case SActionType.act_vocal: this.Vocal( this.ParseDirectString(action.argsDict["name"], ""), this.ParseInt(action.argsDict["vid"], -1), this.musician.VocalDefaultVolume ); break; case SActionType.act_stopvocal: this.Stopvocal(); break; case SActionType.act_title: break; case SActionType.act_save: this.Save( this.ParseString(action.argsDict["filename"], "autosave") ); break; case SActionType.act_load: this.Load( this.ParseString(action.argsDict["filename"], "autosave") ); break; case SActionType.act_label: break; case SActionType.act_switch: this.Switch( this.ParseInt(action.argsDict["id"], 0), this.ParseDirectString(action.argsDict["state"], "on") == "on" ); break; case SActionType.act_var: this.Var( this.ParseDirectString(action.argsDict["name"], "$__LyynehermTempVar"), this.ParseDirectString(action.argsDict["dash"], "1") ); break; case SActionType.act_break: this.Break( action ); break; case SActionType.act_shutdown: this.Shutdown(); break; case SActionType.act_branch: this.Branch( this.ParseDirectString(action.argsDict["link"], "") ); break; case SActionType.act_titlepoint: break; case SActionType.act_trans: this.Trans( this.ParseDirectString(action.argsDict["name"], "Fade") ); break; case SActionType.act_button: this.Button( this.ParseInt(action.argsDict["id"], 0), true, this.ParseDouble(action.argsDict["x"], 0), this.ParseDouble(action.argsDict["y"], 0), this.ParseDirectString(action.argsDict["target"], ""), this.ParseDirectString(action.argsDict["sign"], ""), this.ParseDirectString(action.argsDict["normal"], ""), this.ParseDirectString(action.argsDict["over"], ""), this.ParseDirectString(action.argsDict["on"], ""), this.ParseDirectString(action.argsDict["type"], "once") ); break; case SActionType.act_deletebutton: this.Deletebutton( this.ParseInt(action.argsDict["id"], -1) ); break; case SActionType.act_style: break; case SActionType.act_msglayer: this.MsgLayer( this.ParseInt(action.argsDict["id"], 0) ); break; case SActionType.act_msglayeropt: var dashMsgoptItem = Director.RunMana.CalculatePolish(action.argsDict["dash"]); this.MsgLayerOpt( this.ParseInt(action.argsDict["id"], 0), this.ParseDirectString(action.argsDict["target"], ""), dashMsgoptItem == null ? "" : dashMsgoptItem.ToString() ); break; case SActionType.act_draw: this.DrawCommand( this.ParseInt(action.argsDict["id"], 0), this.ParseDirectString(action.argsDict["dash"], "") ); break; case SActionType.act_dialog: this.Dialog( action.aTag.Substring(0, action.aTag.Length - 2), action.aTag.Last() == '1' ); break; default: break; } }
/// <summary> /// 场景调用 /// </summary> /// <param name="scene">场景实例</param> /// <param name="target">目标标签</param> public void CallScene(Scene scene, SceneAction target = null) { this.CallStack.Submit(scene, target); }
/// <summary> /// 向栈机提交一个场景调用 /// </summary> /// <param name="sc">被调用的场景Scene实例</param> /// <param name="offset">IP偏移</param> public void Submit(Scene sc, SceneAction offset = null) { StackMachineFrame smf = new StackMachineFrame() { State = StackMachineState.Interpreting, ScriptName = sc.Scenario, PC = 0, IP = offset == null ? sc.Ctor : offset, Argv = null, BindingSceneName = sc.Scenario, BindingFunctionName = null, Delay = TimeSpan.FromMilliseconds(0), Tag = "" }; this.coreStack.Push(smf); this.EBP = this.SAVEP = this.coreStack.Peek(); }