// イベントデータ行を読み込んで解析する public CmdData Parse(SRC src, EventDataLine data) { var edata = data.Data; try { // 空行は無視 if (string.IsNullOrWhiteSpace(edata)) { return(new NopCmd(src, data)); } // ラベルは無視 if (Strings.Right(edata, 1) == ":") { return(new NopCmd(src, data)); } // コマンドのパラメータ分割 string[] list; var llength = GeneralLib.ListSplit(edata, out list); // コマンドの種類を判定 switch (Strings.LCase(list[0]) ?? "") { case "arc": return(new ArcCmd(src, data)); case "array": return(new ArrayCmd(src, data)); case "ask": return(new AskCmd(src, data)); case "attack": return(new AttackCmd(src, data)); case "autotalk": return(new AutoTalkCmd(src, data)); case "bossrank": return(new BossRankCmd(src, data)); case "break": return(new BreakCmd(src, data)); case "call": return(new CallCmd(src, data)); case "return": return(new ReturnCmd(src, data)); case "callintermissioncommand": return(new NotImplementedCmd(src, data)); case "cancel": return(new CancelCmd(src, data)); case "center": return(new CenterCmd(src, data)); case "changearea": return(new ChangeAreaCmd(src, data)); case "changelayer": return(new NotImplementedCmd(src, data)); case "changemap": return(new ChangeMapCmd(src, data)); case "changemode": return(new ChangeModeCmd(src, data)); case "changeparty": return(new ChangePartyCmd(src, data)); case "changeterrain": return(new ChangeTerrainCmd(src, data)); case "changeunitbitmap": return(new ChangeUnitBitmapCmd(src, data)); case "charge": return(new ChargeCmd(src, data)); case "circle": return(new CircleCmd(src, data)); case "clearevent": return(new ClearEventCmd(src, data)); case "clearimage": return(new NotSupportedCmd(src, data)); case "clearlayer": return(new NotImplementedCmd(src, data)); case "clearobj": return(new ClearObjCmd(src, data)); case "clearpicture": return(new ClearPictureCmd(src, data)); case "clearskill": return(new ClearSkillCmd(src, data)); case "clearability": return(new ClearSkillCmd(src, data)); case "clearspecialpower": return(new ClearSpecialPowerCmd(src, data)); case "clearmind": return(new ClearSpecialPowerCmd(src, data)); case "clearstatus": return(new ClearStatusCmd(src, data)); case "cls": return(new ClsCmd(src, data)); case "close": return(new CloseCmd(src, data)); case "color": return(new ColorCmd(src, data)); case "colorfilter": return(new ColorFilterCmd(src, data)); case "combine": return(new CombineCmd(src, data)); case "confirm": return(new ConfirmCmd(src, data)); case "continue": return(new ContinueCmd(src, data)); case "copyarray": return(new CopyArrayCmd(src, data)); case "copyfile": return(new CopyFileCmd(src, data)); case "create": return(new CreateCmd(src, data)); case "createfolder": return(new CreateFolderCmd(src, data)); case "debug": return(new DebugCmd(src, data)); case "destroy": return(new DestroyCmd(src, data)); case "disable": return(new DisableCmd(src, data)); case "do": return(new DoCmd(src, data)); case "loop": return(new LoopCmd(src, data)); case "drawoption": return(new DrawOptionCmd(src, data)); case "drawwidth": return(new DrawWidthCmd(src, data)); case "enable": return(new EnableCmd(src, data)); case "equip": return(new EquipCmd(src, data)); case "escape": return(new EscapeCmd(src, data)); case "exchangeitem": return(new ExchangeItemCmd(src, data)); case "exec": return(new NotImplementedCmd(src, data)); case "exit": return(new ExitCmd(src, data)); case "explode": return(new ExplodeCmd(src, data)); case "expup": return(new ExpUpCmd(src, data)); case "fadein": return(new FadeInCmd(src, data)); case "fadeout": return(new FadeOutCmd(src, data)); case "fillcolor": return(new FillColorCmd(src, data)); case "fillstyle": return(new FillStyleCmd(src, data)); case "finish": return(new FinishCmd(src, data)); case "fix": return(new FixCmd(src, data)); case "for": return(new ForCmd(src, data)); case "foreach": return(new ForEachCmd(src, data)); case "next": return(new NextCmd(src, data)); case "font": return(new FontCmd(src, data)); case "forget": return(new ForgetCmd(src, data)); case "gameclear": return(new GameClearCmd(src, data)); case "gameover": return(new GameOverCmd(src, data)); case "freememory": return(new FreeMemoryCmd(src, data)); case "getoff": return(new GetOffCmd(src, data)); case "global": return(new GlobalCmd(src, data)); case "goto": return(new GotoCmd(src, data)); case "hide": return(new HideCmd(src, data)); case "hotpoint": return(new HotPointCmd(src, data)); case "if": return(new IfCmd(src, data)); case "else": return(new ElseCmd(src, data)); case "elseif": return(new ElseIfCmd(src, data)); case "endif": return(new EndIfCmd(src, data)); case "incr": return(new IncrCmd(src, data)); case "increasemorale": return(new IncreaseMoraleCmd(src, data)); case "input": return(new InputCmd(src, data)); case "intermissioncommand": return(new IntermissionCommandCmd(src, data)); case "item": return(new ItemCmd(src, data)); case "join": return(new JoinCmd(src, data)); case "keepbgm": return(new KeepBGMCmd(src, data)); case "land": return(new LandCmd(src, data)); case "launch": return(new LaunchCmd(src, data)); case "leave": return(new LeaveCmd(src, data)); case "levelup": return(new LevelUpCmd(src, data)); case "line": return(new LineCmd(src, data)); case "lineread": return(new LineReadCmd(src, data)); case "load": return(new LoadCmd(src, data)); case "local": return(new LocalCmd(src, data)); case "makepilotlist": return(new MakePilotListCmd(src, data)); case "makeunitlist": return(new MakeUnitListCmd(src, data)); case "mapability": return(new MapAbilityCmd(src, data)); case "mapattack": return(new MapAttackCmd(src, data)); case "mapweapon": return(new MapAttackCmd(src, data)); case "money": return(new MoneyCmd(src, data)); case "monotone": return(new MonotoneCmd(src, data)); case "move": return(new MoveCmd(src, data)); case "night": return(new NightCmd(src, data)); case "noon": return(new NoonCmd(src, data)); case "open": return(new OpenCmd(src, data)); case "option": return(new OptionCmd(src, data)); case "organize": return(new OrganizeCmd(src, data)); case "oval": return(new OvalCmd(src, data)); case "paintpicture": return(new PaintPictureCmd(src, data)); case "paintstring": return(new PaintStringCmd(src, data)); case "paintsysstring": return(new NotImplementedCmd(src, data)); case "pilot": return(new PilotCmd(src, data)); case "playmidi": return(new PlayMIDICmd(src, data)); case "playsound": return(new PlaySoundCmd(src, data)); case "polygon": return(new PolygonCmd(src, data)); case "print": return(new PrintCmd(src, data)); case "pset": return(new PSetCmd(src, data)); case "question": return(new QuestionCmd(src, data)); case "quickload": return(new QuickLoadCmd(src, data)); case "quit": return(new QuitCmd(src, data)); case "rankup": return(new RankUpCmd(src, data)); case "read": return(new NotSupportedCmd(src, data)); case "recoveren": return(new RecoverENCmd(src, data)); case "recoverhp": return(new RecoverHPCmd(src, data)); case "recoverplana": return(new RecoverPlanaCmd(src, data)); case "recoversp": return(new RecoverSPCmd(src, data)); case "redraw": return(new RedrawCmd(src, data)); case "refresh": return(new RefreshCmd(src, data)); case "release": return(new ReleaseCmd(src, data)); case "removefile": return(new RemoveFileCmd(src, data)); case "removefolder": return(new RemoveFolderCmd(src, data)); case "removeitem": return(new RemoveItemCmd(src, data)); case "removepilot": return(new RemovePilotCmd(src, data)); case "removeunit": return(new RemoveUnitCmd(src, data)); case "renamebgm": return(new RenameBGMCmd(src, data)); case "renamefile": return(new RenameFileCmd(src, data)); case "renameterm": return(new RenameTermCmd(src, data)); case "replacepilot": return(new ReplacePilotCmd(src, data)); case "require": return(new RequireCmd(src, data)); case "restoreevent": return(new RestoreEventCmd(src, data)); case "ride": return(new RideCmd(src, data)); case "select": return(new SelectCmd(src, data)); case "savedata": return(new NotImplementedCmd(src, data)); case "selecttarget": return(new SelectTargetCmd(src, data)); case "sepia": return(new SepiaCmd(src, data)); case "set": return(new SetCmd(src, data)); case "setbullet": return(new SetBulletCmd(src, data)); case "setmessage": return(new SetMessageCmd(src, data)); case "setrelation": return(new SetRelationCmd(src, data)); case "setskill": return(new SetSkillCmd(src, data)); case "setability": return(new SetSkillCmd(src, data)); case "setstatus": return(new SetStatusCmd(src, data)); case "setstatusstringcolor": return(new NotImplementedCmd(src, data)); case "setstock": return(new SetStockCmd(src, data)); case "setwindowcolor": return(new NotImplementedCmd(src, data)); case "setwindowframewidth": return(new NotImplementedCmd(src, data)); case "show": return(new ShowCmd(src, data)); case "showimage": return(new NotSupportedCmd(src, data)); case "showunitstatus": return(new ShowUnitStatusCmd(src, data)); case "skip": return(new SkipCmd(src, data)); case "sort": return(new SortCmd(src, data)); case "specialpower": return(new SpecialPowerCmd(src, data)); case "mind": return(new SpecialPowerCmd(src, data)); case "split": return(new SplitCmd(src, data)); case "startbgm": return(new StartBGMCmd(src, data)); case "stopbgm": return(new StopBGMCmd(src, data)); case "stopsummoning": return(new StopSummoningCmd(src, data)); case "supply": return(new SupplyCmd(src, data)); case "sunset": return(new SunsetCmd(src, data)); case "swap": return(new SwapCmd(src, data)); case "switch": return(new SwitchCmd(src, data)); case "playflash": return(new NotSupportedCmd(src, data)); case "clearflash": return(new NotSupportedCmd(src, data)); case "case": if (list.Length == 2) { if (Strings.LCase(list[1]) == "else") { return(new CaseElseCmd(src, data)); } } return(new CaseCmd(src, data)); case "endsw": return(new EndSwCmd(src, data)); case "talk": return(new TalkCmd(src, data)); case "end": return(new EndCmd(src, data)); case "suspend": return(new SuspendCmd(src, data)); case "telop": return(new TelopCmd(src, data)); case "transform": return(new TransformCmd(src, data)); case "unit": return(new UnitCmd(src, data)); case "unset": return(new UnSetCmd(src, data)); case "upgrade": return(new UpgradeCmd(src, data)); case "upvar": return(new UpVarCmd(src, data)); case "useability": return(new UseAbilityCmd(src, data)); case "wait": return(new WaitCmd(src, data)); case "water": return(new WaterCmd(src, data)); case "whitein": return(new WhiteInCmd(src, data)); case "whiteout": return(new WhiteOutCmd(src, data)); case "write": return(new NotSupportedCmd(src, data)); default: { // 定義済みのイベントコマンドではない if (list.Length >= 3) { if (list[1] == "=") { // 代入式 // GetValueAsStringの呼び出しの際に、Argsの内容は必ず項と仮定 // されているので、わざと項にしておく return(new SetCmd(src, new EventDataLine( data.ID, data.Source, data.File, data.LineNum, "Set " + list[0] + " " + "(" + string.Join(" ", list.Skip(2)) + ")" ))); } } if (llength == -1) { return(new NopCmd(src, data)); } // サブルーチンコール? // TODO 多分Talkの中身が壊れる場面がある。 return(new CallCmd(src, new EventDataLine( data.ID, data.Source, data.File, data.LineNum, "Call " + data.Data ))); } } } catch (Exception ex) { src.Log.LogError(ex.Message, ex); src.Event.DisplayEventErrorMessage(data.LineNum, "イベントコマンドの内容が不正です"); return(new NopCmd(src, data)); } }
protected override int ExecInternal() { bool IsList; if (ArgNum != 4) { throw new EventErrorException(this, "Arrayコマンドの引数の数が違います"); } else if (GetArgAsString(4) == "リスト") { IsList = true; } else { IsList = false; } // 代入先の変数名 var var_name = GetArg(2); if (Strings.Left(var_name, 1) == "$") { var_name = Strings.Mid(var_name, 2); } // Eval関数 if (Strings.LCase(Strings.Left(var_name, 5)) == "eval(") { if (Strings.Right(var_name, 1) == ")") { var_name = Strings.Mid(var_name, 6, Strings.Len(var_name) - 6); var_name = Expression.GetValueAsString(var_name); } } // 代入先の変数を初期化した上で再設定 if (Expression.IsSubLocalVariableDefined(var_name)) { // サブルーチンローカル変数の場合 Expression.UndefineVariable(var_name); Event.VarIndex = (Event.VarIndex + 1); Event.VarStack[Event.VarIndex].Init(var_name); } else if (Expression.IsLocalVariableDefined(var_name)) { // ローカル変数の場合 Expression.UndefineVariable(var_name); Expression.DefineLocalVariable(var_name); } else if (Expression.IsGlobalVariableDefined(var_name)) { // グローバル変数の場合 Expression.UndefineVariable(var_name); Expression.DefineGlobalVariable(var_name); } string[] array_buf; if (IsList) { // リストを配列に変換 GeneralLib.ListSplit(GetArgAsString(3), out array_buf); } else { // 文字列を分割して配列に代入 var buf = GetArgAsString(3); var sep = GetArgAsString(4); array_buf = buf.Split(sep); } for (var i = 1; i <= array_buf.Length; i++) { var buf = array_buf[i - 1].Trim(); Expressions.ValueType etype; string str_value; double num_value; if (Information.IsNumeric(buf)) { etype = Expressions.ValueType.NumericType; str_value = ""; num_value = GeneralLib.StrToDbl(buf); } else { etype = Expressions.ValueType.StringType; str_value = buf; num_value = 0d; } var vname = var_name + "[" + i + "]"; Expression.SetVariable(vname, etype, str_value, num_value); } return(EventData.NextID); }
private void ParseArgs(string list) { string[] rawArgs; ArgNum = GeneralLib.ListSplit(list, out rawArgs); // コマンド名も含める foreach (var buf in rawArgs) { var arg = new CmdArgument() { strArg = buf, argType = Expressions.ValueType.UndefinedType, }; args.Add(arg); // 先頭の一文字からパラメータの属性を判定 switch (Strings.Asc(buf)) { case 0: // 空文字列 { arg.argType = Expressions.ValueType.StringType; break; } case 34: // " { if (Strings.Right(buf, 1) == "\"") { if (Strings.InStr(buf, "$(") == 0) { arg.argType = Expressions.ValueType.StringType; arg.strArg = Strings.Mid(buf, 2, Strings.Len(buf) - 2); } } else { arg.argType = Expressions.ValueType.StringType; } break; } case 40: // ( { break; } // 式 case 45: // - { if (Information.IsNumeric(buf)) { arg.lngArg = GeneralLib.StrToLng(buf); arg.dblArg = Conversions.ToDouble(buf); arg.argType = Expressions.ValueType.NumericType; } else { arg.argType = Expressions.ValueType.StringType; } break; } case var @case when 48 <= @case && @case <= 57: // 0~9 { if (Information.IsNumeric(buf)) { arg.lngArg = GeneralLib.StrToLng(buf); arg.dblArg = Conversions.ToDouble(buf); arg.argType = Expressions.ValueType.NumericType; } else { arg.argType = Expressions.ValueType.StringType; } break; } case 96: // ` { if (Strings.Right(buf, 1) == "`") { arg.strArg = Strings.Mid(buf, 2, Strings.Len(buf) - 2); } arg.argType = Expressions.ValueType.StringType; break; } } } }
// ラベルの検索 public int SearchLabel(string lname, int start = -1) { // ラベルの各要素をあらかじめ解析 // XXX Indexがずれていて辛い。 string[] litem; int llen = GeneralLib.ListSplit(lname, out litem); // XXX 死にたい litem = (new string[] { "" }).Concat(litem).ToArray(); // ラベルの種類を判定 LabelType ltype; var lnum = new string[5]; var is_unit = new bool[5]; var is_num = new bool[5]; var is_condition = new bool[5]; var revrersible = false; switch (litem[1] ?? "") { case "プロローグ": { ltype = LabelType.PrologueEventLabel; break; } case "スタート": { ltype = LabelType.StartEventLabel; break; } case "エピローグ": { ltype = LabelType.EpilogueEventLabel; break; } case "ターン": ltype = LabelType.TurnEventLabel; if (Information.IsNumeric(litem[2])) { is_num[2] = true; } lnum[2] = GeneralLib.StrToLng(litem[2]).ToString(); break; case "損傷率": ltype = LabelType.DamageEventLabel; is_unit[2] = true; is_num[3] = true; lnum[3] = GeneralLib.StrToLng(litem[3]).ToString(); break; case "破壊": case "マップ攻撃破壊": ltype = LabelType.DestructionEventLabel; is_unit[2] = true; break; case "全滅": ltype = LabelType.TotalDestructionEventLabel; break; case "攻撃": ltype = LabelType.AttackEventLabel; revrersible = true; is_unit[2] = true; is_unit[3] = true; break; case "攻撃後": ltype = LabelType.AfterAttackEventLabel; revrersible = true; is_unit[2] = true; is_unit[3] = true; break; case "会話": ltype = LabelType.TalkEventLabel; is_unit[2] = true; is_unit[3] = true; break; case "接触": ltype = LabelType.ContactEventLabel; revrersible = true; is_unit[2] = true; is_unit[3] = true; break; case "進入": ltype = LabelType.EnterEventLabel; is_unit[2] = true; if (llen == 4) { is_num[3] = true; is_num[4] = true; lnum[3] = GeneralLib.StrToLng(litem[3]).ToString(); lnum[4] = GeneralLib.StrToLng(litem[4]).ToString(); } break; case "脱出": ltype = LabelType.EscapeEventLabel; is_unit[2] = true; break; case "収納": ltype = LabelType.LandEventLabel; is_unit[2] = true; break; case "使用": ltype = LabelType.UseEventLabel; is_unit[2] = true; break; case "使用後": ltype = LabelType.AfterUseEventLabel; is_unit[2] = true; break; case "変形": ltype = LabelType.TransformEventLabel; is_unit[2] = true; break; case "合体": ltype = LabelType.CombineEventLabel; is_unit[2] = true; break; case "分離": ltype = LabelType.SplitEventLabel; is_unit[2] = true; break; case "行動終了": ltype = LabelType.FinishEventLabel; is_unit[2] = true; break; case "レベルアップ": ltype = LabelType.LevelUpEventLabel; is_unit[2] = true; break; case "勝利条件": ltype = LabelType.RequirementEventLabel; break; case "再開": ltype = LabelType.ResumeEventLabel; break; case "マップコマンド": ltype = LabelType.MapCommandEventLabel; is_condition[3] = true; break; case "ユニットコマンド": ltype = LabelType.UnitCommandEventLabel; is_condition[4] = true; break; case "特殊効果": ltype = LabelType.EffectEventLabel; break; default: ltype = LabelType.NormalLabel; break; } // 各ラベルについて一致しているかチェック foreach (LabelData lab in colEventLabelList.List) { // ラベルの種類が一致している? if (ltype != lab.Name) { continue; } // ClearEventされていない? if (!lab.Enable) { continue; } // 検索開始行より後ろ? if (lab.EventDataId < start) { continue; } // パラメータ数が一致している? if (llen != lab.CountPara()) { if (ltype != LabelType.MapCommandEventLabel && ltype != LabelType.UnitCommandEventLabel) { continue; } } // 各パラメータが一致している? var reversed = false; var isMatch = IsMatch(ltype, lab, litem, lnum, is_unit, is_num, is_condition, reversed); if (!isMatch && revrersible) { // 対象と相手を入れ替えたイベントラベルが存在するか判定 var lname2 = litem[1] + " " + GeneralLib.ListIndex(lab.Data, 3) + " " + GeneralLib.ListIndex(lab.Data, 2); if (lab.AsterNum > 0) { lname2 = "*" + lname2; } if (FindLabel(lname2) == 0) { // 対象と相手を入れ替えて判定し直す reversed = true; isMatch = IsMatch(ltype, lab, litem, lnum, is_unit, is_num, is_condition, reversed); } } if (!isMatch) { continue; } // ここまでたどり付けばラベルは一致している SRC.LogDebug("Found", lab.Name.ToString(), lab.Data); // 対象と相手を入れ替えて一致した場合はグローバル変数も入れ替え if (reversed) { var tmp_u = SelectedUnitForEvent; SelectedUnitForEvent = SelectedTargetForEvent; SelectedTargetForEvent = tmp_u; } return(lab.EventDataId); } return(-1); }