// 属性 aname に対して有効属性を持つか? public bool Effective(string aname) { bool EffectiveRet = default; string c; int i; int slen; // 全属性に有効な場合 if (GeneralLib.InStrNotNest(strEffective, "全") > 0) { EffectiveRet = true; return(EffectiveRet); } if (Strings.Len(aname) == 0) { if (GeneralLib.InStrNotNest(strEffective, "物") > 0) { EffectiveRet = true; } return(EffectiveRet); } i = 1; slen = Strings.Len(strEffective); while (i <= slen) { // 属性をひとまとめずつ取得 c = GeneralLib.GetClassBundle(strEffective, ref i); switch (c ?? "") { case "物": { if (GeneralLib.InStrNotNest(aname, "魔") == 0 && GeneralLib.InStrNotNest(aname, "精") == 0) { EffectiveRet = true; break; } break; } default: { if (GeneralLib.InStrNotNest(aname, c) > 0) { EffectiveRet = true; break; } break; } } i = (i + 1); } return(EffectiveRet); }
// 属性 aname に対して特殊効果無効化属性を持つか? public bool SpecialEffectImmune(string aname) { bool SpecialEffectImmuneRet = default; // 全属性に有効な場合 if (GeneralLib.InStrNotNest(strSpecialEffectImmune, "全") > 0) { SpecialEffectImmuneRet = true; return(SpecialEffectImmuneRet); } if (Strings.Len(aname) == 0) { return(SpecialEffectImmuneRet); } if (GeneralLib.InStrNotNest(strSpecialEffectImmune, aname) > 0) { SpecialEffectImmuneRet = true; return(SpecialEffectImmuneRet); } // 無効化や弱点と違い、クリティカル率のみなので // 「火」に対する防御特性が「弱火」のクリティカル率に影響する点について // 直接関数内に記述できる。 if (Strings.Left(aname, 1) == "弱" || Strings.Left(aname, 1) == "効") { if (GeneralLib.InStrNotNest(strSpecialEffectImmune, aname) > 0) { SpecialEffectImmuneRet = true; return(SpecialEffectImmuneRet); } } return(SpecialEffectImmuneRet); }
// パイロットがユニット u のサポートかどうか public bool IsSupport(Unit u) { if (u.IsFeatureAvailable("ダミーユニット")) { // ダミーユニットの場合はサポートパイロットも通常のパイロットとして扱う return(false); } // サポート指定が存在する? if (GeneralLib.InStrNotNest(Class, "サポート)") == 0) { return(false); } if (u.CountPilot() == 0) { // パイロットが乗っていないユニットの場合は通常パイロットを優先 foreach (var pclass in GeneralLib.ToL(Class)) { var uclass = u.Class; if (uclass == pclass || uclass == (pclass + "(" + get_Nickname(false) + "専用)") || uclass == (pclass + "(" + Name + "専用)") || uclass == (pclass + "(" + Sex + "専用)")) { // 通常のパイロットとして搭乗可能であればサポートでないとみなす return(false); } } } else { // 通常のパイロットとして搭乗している? if (u.Pilots.Contains(this)) { return(false); } } { var uclass = u.Class0; // 通常のサポート? foreach (var pclass in GeneralLib.ToL(Class)) { if ((uclass + "(サポート)" ?? "") == pclass) { return(true); } } // パイロットが乗っていないユニットの場合はここで終了 if (u.CountPilot() == 0) { return(false); } // 専属サポート? var p = u.MainPilot(); foreach (var pclass in GeneralLib.ToL(Class)) { if (pclass == (uclass + "(" + p.Name + "専属サポート)") || pclass == (uclass + "(" + p.get_Nickname(false) + "専属サポート)") || pclass == (uclass + "(" + p.Sex + "専属サポート)")) { return(true); } foreach (var sname in p.Skills.Select(skill => skill.Name)) { if (pclass == (uclass + "(" + sname + "専属サポート)" ?? "")) { return(true); } } } } return(false); }
// 属性 aname に対して無効化属性を持つか? public bool Immune(string aname) { bool ImmuneRet = default; string c; int i; int slen; // 全属性に有効な場合 if (GeneralLib.InStrNotNest(strImmune, "全") > 0) { ImmuneRet = true; return(ImmuneRet); } // 無属性は物理攻撃に分類される if (Strings.Len(aname) == 0) { if (GeneralLib.InStrNotNest(strImmune, "物") > 0) { ImmuneRet = true; } return(ImmuneRet); } // 属性に該当するかを判定 i = 1; slen = Strings.Len(strImmune); while (i <= slen) { // 属性をひとまとめずつ取得 c = GeneralLib.GetClassBundle(strImmune, ref i); switch (c ?? "") { case "物": { if (GeneralLib.InStrNotNest(aname, "魔") == 0 && GeneralLib.InStrNotNest(aname, "精") == 0) { ImmuneRet = true; break; } break; } case "魔": { // 魔法武器以外の魔属性なら特性が有効 if (GeneralLib.InStrNotNest(aname, "魔") > 0 && GeneralLib.InStrNotNest(aname, "魔武") == 0 && GeneralLib.InStrNotNest(aname, "魔突") == 0 && GeneralLib.InStrNotNest(aname, "魔接") == 0 && GeneralLib.InStrNotNest(aname, "魔銃") == 0 && GeneralLib.InStrNotNest(aname, "魔実") == 0) { ImmuneRet = true; break; } break; } default: { if (GeneralLib.InStrNotNest(aname, c) > 0) { ImmuneRet = true; break; } break; } } i = (i + 1); } return(ImmuneRet); }
// 属性の該当判定 // aclass1 が防御属性、aclass2 が武器属性 public bool IsAttributeClassified(string aclass1, string aclass2) { bool IsAttributeClassifiedRet = default; string attr; int alen, i; var with_not = default(bool); if (Strings.Len(aclass1) == 0) { IsAttributeClassifiedRet = true; return(IsAttributeClassifiedRet); } if (aclass1 == "全") { IsAttributeClassifiedRet = true; return(IsAttributeClassifiedRet); } // 無属性の攻撃は物理攻撃に分類される if (Strings.Len(aclass2) == 0) { if (GeneralLib.InStrNotNest(aclass1, "物") > 0) { IsAttributeClassifiedRet = true; } if (GeneralLib.InStrNotNest(aclass1, "!") > 0) { IsAttributeClassifiedRet = !IsAttributeClassifiedRet; } goto EndOfFunction; } i = 1; alen = Strings.Len(aclass1); while (i <= alen) { attr = GeneralLib.GetClassBundle(aclass1, ref i); switch (attr ?? "") { case "物": { if (GeneralLib.InStrNotNest(aclass2, "魔") == 0 && GeneralLib.InStrNotNest(aclass2, "精") == 0) { IsAttributeClassifiedRet = true; break; } break; } case "魔": { // 魔法武器以外の魔属性なら特性が有効 if (GeneralLib.InStrNotNest(aclass2, "魔") > 0) { if (GeneralLib.InStrNotNest(aclass2, "魔武") == 0 && GeneralLib.InStrNotNest(aclass2, "魔突") == 0 && GeneralLib.InStrNotNest(aclass2, "魔接") == 0 && GeneralLib.InStrNotNest(aclass2, "魔銃") == 0 && GeneralLib.InStrNotNest(aclass2, "魔実") == 0) { IsAttributeClassifiedRet = true; } else if (with_not) { IsAttributeClassifiedRet = true; } break; } break; } case "!": { with_not = true; break; } default: { if (GeneralLib.InStrNotNest(aclass2, attr) > 0) { IsAttributeClassifiedRet = true; break; } break; } } i = (i + 1); } EndOfFunction: ; if (with_not) { IsAttributeClassifiedRet = !IsAttributeClassifiedRet; } return(IsAttributeClassifiedRet); }
protected override int ExecInternal() { string ustatus; string vname; Event.ForEachSet = new List <string>(); switch (ArgNum) { // ユニットに対するForEach case 2: case 3: { if (ArgNum == 2) { ustatus = "出撃 格納"; } else { ustatus = GetArgAsString(3); if (ustatus == "全て") { ustatus = "全"; } } switch (GetArgAsString(2) ?? "") { case "全": if (ustatus == "全") { foreach (Unit u in SRC.UList.Items) { if (u.Status != "他形態" && u.Status != "旧主形態" && u.Status != "旧形態" && u.Status != "破棄") { Event.ForEachSet.Add(u.ID); } } } else { foreach (Unit u in SRC.UList.Items) { if (Strings.InStr(ustatus, u.Status) > 0) { Event.ForEachSet.Add(u.ID); } } } break; case "味方": case "NPC": case "敵": case "中立": { var uparty = GetArgAsString(2); if (ustatus == "全") { foreach (Unit u in SRC.UList.Items) { if ((u.Party0 ?? "") == (uparty ?? "")) { if (u.Status != "他形態" && u.Status != "旧主形態" && u.Status != "旧形態" && u.Status != "破棄") { Event.ForEachSet.Add(u.ID); } } } } else { foreach (Unit u in SRC.UList.Items) { if ((u.Party0 ?? "") == (uparty ?? "")) { if (Strings.InStr(ustatus, u.Status) > 0) { Event.ForEachSet.Add(u.ID); } } } } break; } default: var ugroup = GetArgAsString(2); if (ustatus == "全て") { ustatus = "全"; } foreach (Unit u in SRC.UList.Items) { if (u.CountPilot() > 0) { if ((u.MainPilot().ID ?? "") == (ugroup ?? "") || Strings.InStr(u.MainPilot().ID, ugroup + ":") == 1) { if (ustatus == "全") { if (u.Status != "他形態" && u.Status != "旧主形態" && u.Status != "旧形態" && u.Status != "破棄") { Event.ForEachSet.Add(u.ID); } } else if (Strings.InStr(ustatus, u.Status) > 0) { Event.ForEachSet.Add(u.ID); } } } } break; } break; } // 配列の要素に対するForEach case 4: { // インデックス用変数名 vname = GetArg(2); if (Strings.Left(vname, 1) == "$") { vname = Strings.Mid(vname, 2); } // 配列の変数名 var aname = GetArg(4); if (Strings.Left(aname, 1) == "$") { aname = Strings.Mid(aname, 2); } // Eval関数 if (Strings.LCase(Strings.Left(aname, 5)) == "eval(") { if (Strings.Right(aname, 1) == ")") { aname = Strings.Mid(aname, 6, Strings.Len(aname) - 6); aname = Expression.GetValueAsString(aname); } } // 配列を検索し、配列要素を見つける if (GeneralLib.InStrNotNest(aname, "パイロット一覧(") == 1) { // 配列作成 var pilots = SRC.PList.Items.Where(p => p.Alive && !p.Away) // XXX メインパイロットが差し変わっていたら除外? .Where(p => !(p.Unit != null && p.Unit.CountPilot() > 0 && p == p.Unit.MainPilot() && p != p.Unit.Pilots.First())); // ソート var key_type = Expression.GetValueAsString(aname.InsideKakko()); if (key_type == "名称") { pilots = pilots.OrderBy(x => x.KanaName); } else { pilots = pilots.OrderByDescending(p => { switch (key_type ?? "") { case "レベル": return(500 * p.Level + p.Exp); case "SP": return(p.MaxSP); case "格闘": return(p.Infight); case "射撃": return(p.Shooting); case "命中": return(p.Hit); case "回避": return(p.Dodge); case "技量": return(p.Technique); case "反応": return(p.Intuition); default: return(0); } }); } pilots.ToList().ForEach(p => Event.ForEachSet.Add(p.ID)); } else if (GeneralLib.InStrNotNest(aname, "ユニット一覧(") == 1) { // 配列作成 var units = SRC.UList.Items.Where(u => u.Status == "出撃" || u.Status == "格納" || u.Status == "待機"); var key_type = Expression.GetValueAsString(aname.InsideKakko()); if (key_type == "名称") { units = units.OrderBy(x => x.KanaName); } else { units = units.OrderByDescending(u => { switch (key_type ?? "") { case "ランク": return(u.Rank); case "HP": return(u.HP); case "EN": return(u.EN); case "装甲": return(u.get_Armor("")); case "運動性": return(u.get_Mobility("")); case "移動力": return(u.Speed); case "最大攻撃力": return(u.Weapons .Where(x => x.IsEnable()) .Where(x => !x.IsWeaponClassifiedAs("合")) .Select(x => x.WeaponPower("")) .Append(0) .Max()); case "最長射程": return(u.Weapons .Where(x => x.IsEnable()) .Where(x => !x.IsWeaponClassifiedAs("合")) .Select(x => x.WeaponMaxRange()) .Append(0) .Max()); default: return(0); } }); } units.ToList().ForEach(u => Event.ForEachSet.Add(u.ID)); } else { if (Expression.IsSubLocalVariableDefined(aname)) { // サブルーチンローカルな配列に対するForEach Event.SubLocalVars().ArrayIndexesByName(aname).ToList().ForEach(x => Event.ForEachSet.Add(x)); } else if (Expression.IsLocalVariableDefined(aname)) { // ローカルな配列に対するForEach Event.LocalVariableList.Values.ArrayIndexesByName(aname).ToList().ForEach(x => Event.ForEachSet.Add(x)); } else if (Expression.IsGlobalVariableDefined(aname)) { // グローバルな配列に対するForEach Event.GlobalVariableList.Values.ArrayIndexesByName(aname).ToList().ForEach(x => Event.ForEachSet.Add(x)); } // リストに対するForEach if (Event.ForEachSet.Count == 0) { var buf = Expression.GetValueAsString(aname); Event.ForEachSet = GeneralLib.ToList(buf); } } break; } default: throw new EventErrorException(this, "ForEachコマンドの引数の数が違います"); } if (Event.ForEachSet.Count > 0) { // ForEachの実行要素がある場合 Event.ForEachIndex = 1; Event.ForIndex = (Event.ForIndex + 1); if (ArgNum < 4) { Event.SelectedUnitForEvent = SRC.UList.Item(Event.ForEachSet[0]); } else { Expression.SetVariableAsString(GetArg(2), Event.ForEachSet[0]); } return(EventData.NextID); } else { // ForEachの実行要素がない場合 // 対応するNextを探す var depth = 1; foreach (var i in AfterEventIdRange()) { var cmd = Event.EventCmd[i]; switch (cmd.Name) { case CmdType.ForCmd: case CmdType.ForEachCmd: depth = (depth + 1); break; case CmdType.NextCmd: depth = (depth - 1); if (depth == 0) { return(cmd.EventData.NextID); } break; } } throw new EventErrorException(this, "ForまたはForEachとNextが対応していません"); } }