public static string GetBattleDetail(BattleData battle)
        {
            var  sbmaster      = new StringBuilder();
            bool isBaseAirRaid = battle.IsBaseAirRaid;


            foreach (var phase in battle.GetPhases())
            {
                var sb = new StringBuilder();

                if (phase is PhaseBaseAirRaid)
                {
                    var p = phase as PhaseBaseAirRaid;

                    sb.AppendLine("味方基地航空隊 参加中隊:");
                    sb.Append(" ").AppendLine(string.Join(", ", p.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString()).DefaultIfEmpty("(なし)")));

                    GetBattleDetailPhaseAirBattle(sb, p);
                }
                else if (phase is PhaseAirBattle)
                {
                    var p = phase as PhaseAirBattle;

                    GetBattleDetailPhaseAirBattle(sb, p);
                }
                else if (phase is PhaseBaseAirAttack)
                {
                    var p = phase as PhaseBaseAirAttack;

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat("〈第{0}波〉\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine("味方基地航空隊 参加中隊:");
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }
                }
                else if (phase is PhaseJetAirBattle)
                {
                    var p = phase as PhaseJetAirBattle;

                    GetBattleDetailPhaseAirBattle(sb, p);
                }
                else if (phase is PhaseJetBaseAirAttack)
                {
                    var p = phase as PhaseJetBaseAirAttack;

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat("〈第{0}波〉\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine("味方基地航空隊 参加中隊:");
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }
                }
                else if (phase is PhaseInitial)
                {
                    var p = phase as PhaseInitial;

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine("〈味方主力艦隊〉");
                    }
                    else
                    {
                        sb.AppendLine("〈味方艦隊〉");
                    }

                    if (isBaseAirRaid)
                    {
                        OutputFriendBase(sb, p.FriendInitialHPs, p.FriendMaxHPs);
                    }
                    else
                    {
                        OutputFriendData(sb, p.FriendFleet, p.FriendInitialHPs, p.FriendMaxHPs);
                    }

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("〈味方随伴艦隊〉");

                        OutputFriendData(sb, p.FriendFleetEscort, p.FriendInitialHPsEscort, p.FriendMaxHPsEscort);
                    }

                    sb.AppendLine();

                    if (p.EnemyMembersEscort != null)
                    {
                        sb.Append("〈敵主力艦隊〉");
                    }
                    else
                    {
                        sb.Append("〈敵艦隊〉");
                    }

                    if (p.IsBossDamaged)
                    {
                        sb.Append(" : 装甲破壊");
                    }
                    sb.AppendLine();

                    OutputEnemyData(sb, p.EnemyMembersInstance, p.EnemyLevels, p.EnemyInitialHPs, p.EnemyMaxHPs, p.EnemySlotsInstance, p.EnemyParameters);


                    if (p.EnemyMembersEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("〈敵随伴艦隊〉");

                        OutputEnemyData(sb, p.EnemyMembersEscortInstance, p.EnemyLevelsEscort, p.EnemyInitialHPsEscort, p.EnemyMaxHPsEscort, p.EnemySlotsEscortInstance, p.EnemyParametersEscort);
                    }

                    sb.AppendLine();

                    if (battle.GetPhases().Where(ph => ph is PhaseBaseAirAttack || ph is PhaseBaseAirRaid).Any(ph => ph != null && ph.IsAvailable))
                    {
                        sb.AppendLine("〈基地航空隊〉");
                        GetBattleDetailBaseAirCorps(sb, KCDatabase.Instance.Battle.Compass.MapAreaID);                              // :(
                        sb.AppendLine();
                    }

                    if (p.RationIndexes.Length > 0)
                    {
                        sb.AppendLine("〈戦闘糧食補給〉");
                        foreach (var index in p.RationIndexes)
                        {
                            var ship = p.GetFriendShip(index);

                            if (ship != null)
                            {
                                sb.AppendFormat(" {0} #{1}\r\n", ship.NameWithLevel, index + 1);
                            }
                        }
                        sb.AppendLine();
                    }
                }
                else if (phase is PhaseNightBattle)
                {
                    var p      = phase as PhaseNightBattle;
                    int length = sb.Length;

                    {
                        var eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftFriend];
                        if (eq != null)
                        {
                            sb.Append("自軍夜間触接: ").AppendLine(eq.Name);
                        }
                        eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftEnemy];
                        if (eq != null)
                        {
                            sb.Append("敵軍夜間触接: ").AppendLine(eq.Name);
                        }
                    }

                    {
                        int searchlightIndex = p.SearchlightIndexFriend;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat("自軍探照灯照射: {0} #{1}\r\n", p.FriendFleet.MembersInstance[searchlightIndex].Name, searchlightIndex + 1);
                        }
                        searchlightIndex = p.SearchlightIndexEnemy;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat("敵軍探照灯照射: {0} #{1}\r\n", p.EnemyMembersInstance[searchlightIndex].NameWithClass, searchlightIndex + 1);
                        }
                    }

                    if (p.FlareIndexFriend != -1)
                    {
                        sb.AppendFormat("自軍照明弾投射: {0} #{1}\r\n", p.FriendFleet.MembersInstance[p.FlareIndexFriend].Name, p.FlareIndexFriend + 1);
                    }
                    if (p.FlareIndexEnemy != -1)
                    {
                        sb.AppendFormat("敵軍照明弾投射: {0} #{1}\r\n", p.FlareEnemyInstance.NameWithClass, p.FlareIndexEnemy + 1);
                    }

                    if (sb.Length > length)                         // 追加行があった場合
                    {
                        sb.AppendLine();
                    }
                }
                else if (phase is PhaseSearching)
                {
                    var p = phase as PhaseSearching;

                    sb.Append("自軍陣形: ").Append(Constants.GetFormation(p.FormationFriend));
                    sb.Append(" / 敵軍陣形: ").AppendLine(Constants.GetFormation(p.FormationEnemy));
                    sb.Append("交戦形態: ").AppendLine(Constants.GetEngagementForm(p.EngagementForm));
                    sb.Append("自軍索敵: ").Append(Constants.GetSearchingResult(p.SearchingFriend));
                    sb.Append(" / 敵軍索敵: ").AppendLine(Constants.GetSearchingResult(p.SearchingEnemy));

                    sb.AppendLine();
                }
                else if (phase is PhaseSupport)
                {
                    var p = phase as PhaseSupport;

                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈支援艦隊〉");
                        OutputSupportData(sb, p.SupportFleet);
                        sb.AppendLine();
                    }
                }


                if (!(phase is PhaseBaseAirAttack || phase is PhaseJetBaseAirAttack))                       // 通常出力と重複するため
                {
                    sb.Append(phase.GetBattleDetail());
                }

                if (sb.Length > 0)
                {
                    sbmaster.AppendFormat("《{0}》\r\n", phase.Title).Append(sb);
                }
            }


            {
                sbmaster.AppendLine("《戦闘終了》");

                var friend       = battle.Initial.FriendFleet;
                var friendescort = battle.Initial.FriendFleetEscort;
                var enemy        = battle.Initial.EnemyMembersInstance;
                var enemyescort  = battle.Initial.EnemyMembersEscortInstance;

                if (friendescort != null)
                {
                    sbmaster.AppendLine("〈味方主力艦隊〉");
                }
                else
                {
                    sbmaster.AppendLine("〈味方艦隊〉");
                }

                if (isBaseAirRaid)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (battle.Initial.FriendMaxHPs[i] <= 0)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, string.Format("第{0}基地", i + 1),
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < friend.Members.Count(); i++)
                    {
                        var ship = friend.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, ship.Name,
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }

                if (friendescort != null)
                {
                    sbmaster.AppendLine().AppendLine("〈味方随伴艦隊〉");

                    for (int i = 0; i < friendescort.Members.Count(); i++)
                    {
                        var ship = friendescort.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.Name,
                                         battle.Initial.FriendInitialHPsEscort[i], battle.ResultHPs[i + 6], battle.Initial.FriendMaxHPsEscort[i]);
                    }
                }


                sbmaster.AppendLine();
                if (enemyescort != null)
                {
                    sbmaster.AppendLine("〈敵主力艦隊〉");
                }
                else
                {
                    sbmaster.AppendLine("〈敵艦隊〉");
                }

                for (int i = 0; i < enemy.Length; i++)
                {
                    var ship = enemy[i];
                    if (ship == null)
                    {
                        continue;
                    }

                    OutputResultData(sbmaster, i,
                                     ship.NameWithClass,
                                     battle.Initial.EnemyInitialHPs[i], battle.ResultHPs[i + 12], battle.Initial.EnemyMaxHPs[i]);
                }

                if (enemyescort != null)
                {
                    sbmaster.AppendLine().AppendLine("〈敵随伴艦隊〉");

                    for (int i = 0; i < enemyescort.Length; i++)
                    {
                        var ship = enemyescort[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.NameWithClass,
                                         battle.Initial.EnemyInitialHPsEscort[i], battle.ResultHPs[i + 18], battle.Initial.EnemyMaxHPsEscort[i]);
                    }
                }

                sbmaster.AppendLine();
            }

            return(sbmaster.ToString());
        }
        public static string GetBattleDetail(BattleData battle)
        {
            var  sbmaster      = new StringBuilder();
            bool isBaseAirRaid = battle.IsBaseAirRaid;


            foreach (var phase in battle.GetPhases())
            {
                var sb = new StringBuilder();

                switch (phase)
                {
                case PhaseBaseAirRaid p:

                    sb.AppendLine(ConstantsRes.BattleDetail_AirAttackUnits);
                    sb.Append(" ").AppendLine(string.Join(", ", p.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString()).DefaultIfEmpty("(empty)")));

                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseAirBattle p:

                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseBaseAirAttack p:

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_AirAttackWave + "\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine(ConstantsRes.BattleDetail_AirAttackUnits);
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }

                    break;

                case PhaseJetAirBattle p:
                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseJetBaseAirAttack p:

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_AirAttackWave + "\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine(ConstantsRes.BattleDetail_AirAttackUnits);
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }

                    break;

                case PhaseInitial p:


                    if (p.FriendFleetEscort != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_FriendMainFleet);
                    }
                    else
                    {
                        sb.Append(ConstantsRes.BattleDetail_FriendFleet);
                    }


                    void appendFleetInfo(FleetData fleet)
                    {
                        sb.Append(" Air Superiority ");
                        sb.Append(GetRangeString(Calculator.GetAirSuperiority(fleet, false), Calculator.GetAirSuperiority(fleet, true)));

                        double truncate2(double value) => Math.Floor(value * 100) / 100;

                        sb.AppendFormat(" / LOS [1] {0}, [2] {1}, [3] {2}, [4] {3}",
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 1)),
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 2)),
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 3)),
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 4)));
                    }

                    if (isBaseAirRaid)
                    {
                        sb.AppendLine();
                        OutputFriendBase(sb, p.FriendInitialHPs, p.FriendMaxHPs);
                    }
                    else
                    {
                        appendFleetInfo(p.FriendFleet);
                        sb.AppendLine();
                        OutputFriendData(sb, p.FriendFleet, p.FriendInitialHPs, p.FriendMaxHPs);
                    }

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine();
                        sb.Append(ConstantsRes.BattleDetail_FriendEscortFleet);
                        appendFleetInfo(p.FriendFleetEscort);
                        sb.AppendLine();

                        OutputFriendData(sb, p.FriendFleetEscort, p.FriendInitialHPsEscort, p.FriendMaxHPsEscort);
                    }


                    sb.AppendLine();


                    void appendEnemyFleetInfo(int[] members)
                    {
                        int  air           = 0;
                        int  airbase       = 0;
                        bool indeterminate = false;

                        for (int i = 0; i < members.Length; i++)
                        {
                            var param = RecordManager.Instance.ShipParameter[members[i]];
                            if (param == null)
                            {
                                continue;
                            }

                            if (param.DefaultSlot == null || param.Aircraft == null)
                            {
                                indeterminate = true;
                                continue;
                            }

                            for (int s = 0; s < Math.Min(param.DefaultSlot.Length, param.Aircraft.Length); s++)
                            {
                                air += Calculator.GetAirSuperiority(param.DefaultSlot[s], param.Aircraft[s]);
                                if (KCDatabase.Instance.MasterEquipments[param.DefaultSlot[s]]?.IsAircraft ?? false)
                                {
                                    airbase += Calculator.GetAirSuperiority(param.DefaultSlot[s], param.Aircraft[s], 0, 0, 1);
                                }
                            }
                        }
                        sb.AppendFormat(" AS {0} (Air Base {1})", air, airbase);
                        if (indeterminate)
                        {
                            sb.Append(" (To be determined)");
                        }
                    }

                    if (p.EnemyMembersEscort != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_EnemyMainFleet);
                    }
                    else
                    {
                        sb.Append(ConstantsRes.BattleDetail_EnemyFleet);
                    }

                    appendEnemyFleetInfo(p.EnemyMembers);

                    if (p.IsBossDamaged)
                    {
                        sb.Append(" : Boss Debuffed");
                    }
                    sb.AppendLine();

                    OutputEnemyData(sb, p.EnemyMembersInstance, p.EnemyLevels, p.EnemyInitialHPs, p.EnemyMaxHPs, p.EnemySlotsInstance, p.EnemyParameters);


                    if (p.EnemyMembersEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine(ConstantsRes.BattleDetail_EnemyEscortFleet);

                        appendEnemyFleetInfo(p.EnemyMembersEscort);
                        sb.AppendLine();

                        OutputEnemyData(sb, p.EnemyMembersEscortInstance, p.EnemyLevelsEscort, p.EnemyInitialHPsEscort, p.EnemyMaxHPsEscort, p.EnemySlotsEscortInstance, p.EnemyParametersEscort);
                    }

                    sb.AppendLine();

                    if (battle.GetPhases().Where(ph => ph is PhaseBaseAirAttack || ph is PhaseBaseAirRaid).Any(ph => ph != null && ph.IsAvailable))
                    {
                        sb.AppendLine(ConstantsRes.BattleDetail_AirBase);
                        GetBattleDetailBaseAirCorps(sb, KCDatabase.Instance.Battle.Compass.MapAreaID);                                      // :(
                        sb.AppendLine();
                    }

                    if (p.RationIndexes.Length > 0)
                    {
                        sb.AppendLine("〈Combat Ration〉");
                        foreach (var index in p.RationIndexes)
                        {
                            var ship = p.GetFriendShip(index);

                            if (ship != null)
                            {
                                sb.AppendFormat(" {0} #{1}\r\n", ship.NameWithLevel, index + 1);
                            }
                        }
                        sb.AppendLine();
                    }

                    break;

                case PhaseNightInitial p:

                {
                    var eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftFriend];
                    if (eq != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_FriendlyNightContact).AppendLine(eq.Name);
                    }
                    eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftEnemy];
                    if (eq != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_EnemyNightContact).AppendLine(eq.Name);
                    }
                }

                    {
                        int searchlightIndex = p.SearchlightIndexFriend;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat(ConstantsRes.BattleDetail_FriendlySearchlight + "\r\n", p.FriendFleet.MembersInstance[searchlightIndex].Name, searchlightIndex + 1);
                        }
                        searchlightIndex = p.SearchlightIndexEnemy;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat(ConstantsRes.BattleDetail_EnemySearchlight + "\r\n", p.EnemyMembersInstance[searchlightIndex].NameWithClass, searchlightIndex + 1);
                        }
                    }

                    if (p.FlareIndexFriend != -1)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_FriendlySearchlight + "\r\n", p.FlareFriendInstance.NameWithLevel, p.FlareIndexFriend + 1);
                    }
                    if (p.FlareIndexEnemy != -1)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_EnemySearchlight + "\r\n", p.FlareEnemyInstance.NameWithClass, p.FlareIndexEnemy + 1);
                    }

                    sb.AppendLine();
                    break;


                case PhaseSearching p:
                    sb.Append("Formation: ").Append(Constants.GetFormation(p.FormationFriend));
                    sb.Append(" / Enemy Formation: ").AppendLine(Constants.GetFormation(p.FormationEnemy));
                    sb.Append("Engagement: ").AppendLine(Constants.GetEngagementForm(p.EngagementForm));
                    sb.Append("Contact: ").Append(Constants.GetSearchingResult(p.SearchingFriend));
                    sb.Append(" / Enemy Contact: ").AppendLine(Constants.GetSearchingResult(p.SearchingEnemy));

                    sb.AppendLine();

                    break;

                case PhaseSupport p:
                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈Support Fleet〉");
                        OutputSupportData(sb, p.SupportFleet);
                        sb.AppendLine();
                    }
                    break;

                case PhaseFriendlySupport p:
                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈Friendly Fleet〉");
                        OutputFriendlySupportData(sb, p);
                        sb.AppendLine();

                        {
                            int searchlightIndex = p.SearchlightIndexFriend;
                            if (searchlightIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_FriendlySearchlight + "\r\n", p.SearchlightFriendInstance.NameWithClass, searchlightIndex + 1);
                            }
                            searchlightIndex = p.SearchlightIndexEnemy;
                            if (searchlightIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_EnemySearchlight + "\r\n", p.SearchlightEnemyInstance.NameWithClass, searchlightIndex + 1);
                            }
                        }

                        {
                            int flareIndex = p.FlareIndexFriend;
                            if (flareIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_FriendlyStarshell + "\r\n", p.FlareFriendInstance.NameWithClass, flareIndex + 1);
                            }
                            flareIndex = p.FlareIndexEnemy;
                            if (flareIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_EnemyStarshell + "\r\n", p.FlareEnemyInstance.NameWithClass, flareIndex + 1);
                            }
                        }

                        sb.AppendLine();
                    }
                    break;
                }


                if (!(phase is PhaseBaseAirAttack || phase is PhaseJetBaseAirAttack))                       // 通常出力と重複するため
                {
                    sb.Append(phase.GetBattleDetail());
                }

                if (sb.Length > 0)
                {
                    sbmaster.AppendFormat("== {0} ==\r\n", phase.Title).Append(sb);
                }
            }


            {
                sbmaster.AppendLine(ConstantsRes.BattleDetail_BattleEnd);

                var friend       = battle.Initial.FriendFleet;
                var friendescort = battle.Initial.FriendFleetEscort;
                var enemy        = battle.Initial.EnemyMembersInstance;
                var enemyescort  = battle.Initial.EnemyMembersEscortInstance;

                if (friendescort != null)
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_FriendMainFleet);
                }
                else
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_FriendFleet);
                }

                if (isBaseAirRaid)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (battle.Initial.FriendMaxHPs[i] <= 0)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, string.Format("Base {0}", i + 1),
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < friend.Members.Count(); i++)
                    {
                        var ship = friend.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, ship.Name,
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }

                if (friendescort != null)
                {
                    sbmaster.AppendLine().AppendLine(ConstantsRes.BattleDetail_FriendEscortFleet);

                    for (int i = 0; i < friendescort.Members.Count(); i++)
                    {
                        var ship = friendescort.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.Name,
                                         battle.Initial.FriendInitialHPsEscort[i], battle.ResultHPs[i + 6], battle.Initial.FriendMaxHPsEscort[i]);
                    }
                }


                sbmaster.AppendLine();
                if (enemyescort != null)
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_EnemyMainFleet);
                }
                else
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_EnemyFleet);
                }

                for (int i = 0; i < enemy.Length; i++)
                {
                    var ship = enemy[i];
                    if (ship == null)
                    {
                        continue;
                    }

                    OutputResultData(sbmaster, i,
                                     ship.NameWithClass,
                                     battle.Initial.EnemyInitialHPs[i], battle.ResultHPs[i + 12], battle.Initial.EnemyMaxHPs[i]);
                }

                if (enemyescort != null)
                {
                    sbmaster.AppendLine().AppendLine(ConstantsRes.BattleDetail_EnemyEscortFleet);

                    for (int i = 0; i < enemyescort.Length; i++)
                    {
                        var ship = enemyescort[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.NameWithClass,
                                         battle.Initial.EnemyInitialHPsEscort[i], battle.ResultHPs[i + 18], battle.Initial.EnemyMaxHPsEscort[i]);
                    }
                }

                sbmaster.AppendLine();
            }

            return(sbmaster.ToString());
        }
        public static string GetBattleDetail(BattleData battle)
        {
            var sbmaster = new StringBuilder();

            foreach (var phase in battle.GetPhases())
            {
                var sb = new StringBuilder();

                if (phase is PhaseAirBattle)
                {
                    var p = phase as PhaseAirBattle;

                    GetBattleDetailPhaseAirBattle(sb, p);
                }
                else if (phase is PhaseBaseAirAttack)
                {
                    var p = phase as PhaseBaseAirAttack;

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat("〈第{0}波〉\r\n", a.AirAttackIndex + 1);
                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }
                }
                else if (phase is PhaseInitial)
                {
                    var p = phase as PhaseInitial;

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine("〈味方主力艦隊〉");
                    }
                    else
                    {
                        sb.AppendLine("〈味方艦隊〉");
                    }

                    OutputFriendData(sb, p.FriendFleet, p.InitialHPs.Take(6).ToArray(), p.MaxHPs.Take(6).ToArray());

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("〈味方随伴艦隊〉");

                        OutputFriendData(sb, p.FriendFleetEscort, p.InitialHPs.Skip(12).Take(6).ToArray(), p.MaxHPs.Skip(12).Take(6).ToArray());
                    }

                    sb.AppendLine();

                    if (p.EnemyMembersEscort != null)
                    {
                        sb.Append("〈敵主力艦隊〉");
                    }
                    else
                    {
                        sb.Append("〈敵艦隊〉");
                    }

                    if (p.IsBossDamaged)
                    {
                        sb.Append(" : 装甲破壊");
                    }
                    sb.AppendLine();

                    OutputEnemyData(sb, p.EnemyMembersInstance, p.EnemyLevels, p.InitialHPs.Skip(6).Take(6).ToArray(), p.MaxHPs.Skip(6).Take(6).ToArray(), p.EnemySlotsInstance, p.EnemyParameters);


                    if (p.EnemyMembersEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("〈敵随伴艦隊〉");

                        OutputEnemyData(sb, p.EnemyMembersEscortInstance, p.EnemyLevelsEscort, p.InitialHPs.Skip(18).Take(6).ToArray(), p.MaxHPs.Skip(18).Take(6).ToArray(), p.EnemySlotsEscortInstance, p.EnemyParametersEscort);
                    }

                    sb.AppendLine();
                }
                else if (phase is PhaseNightBattle)
                {
                    var p      = phase as PhaseNightBattle;
                    int length = sb.Length;

                    {
                        var eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftFriend];
                        if (eq != null)
                        {
                            sb.Append("自軍夜間触接: ").AppendLine(eq.Name);
                        }
                        eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftEnemy];
                        if (eq != null)
                        {
                            sb.Append("敵軍夜間触接: ").AppendLine(eq.Name);
                        }
                    }

                    {
                        int searchlightIndex = p.SearchlightIndexFriend;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat("自軍探照灯照射: {0} #{1}\r\n", p.FriendFleet.MembersInstance[searchlightIndex].Name, searchlightIndex + 1);
                        }
                        searchlightIndex = p.SearchlightIndexEnemy;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat("敵軍探照灯照射: {0} #{1}\r\n", p.EnemyMembersInstance[searchlightIndex].NameWithClass, searchlightIndex + 1);
                        }
                    }

                    if (p.FlareIndexFriend != -1)
                    {
                        sb.AppendFormat("自軍照明弾投射: {0} #{1}\r\n", p.FriendFleet.MembersInstance[p.FlareIndexFriend].Name, p.FlareIndexFriend + 1);
                    }
                    if (p.FlareIndexEnemy != -1)
                    {
                        sb.AppendFormat("敵軍照明弾投射: {0} #{1}\r\n", p.FlareEnemyInstance.NameWithClass, p.FlareIndexEnemy + 1);
                    }

                    if (sb.Length > length)                                     // 追加行があった場合
                    {
                        sb.AppendLine();
                    }
                }
                else if (phase is PhaseSearching)
                {
                    var p = phase as PhaseSearching;

                    sb.Append("自軍陣形: ").Append(Constants.GetFormation(p.FormationFriend));
                    sb.Append(" / 敵軍陣形: ").AppendLine(Constants.GetFormation(p.FormationEnemy));
                    sb.Append("交戦形態: ").AppendLine(Constants.GetEngagementForm(p.EngagementForm));
                    sb.Append("自軍索敵: ").Append(Constants.GetSearchingResult(p.SearchingFriend));
                    sb.Append(" / 敵軍索敵: ").AppendLine(Constants.GetSearchingResult(p.SearchingEnemy));

                    sb.AppendLine();
                }


                if (!(phase is PhaseBaseAirAttack))                             // 通常出力と重複するため
                {
                    sb.Append(phase.GetBattleDetail());
                }

                if (sb.Length > 0)
                {
                    sbmaster.AppendFormat("《{0}》\r\n", phase.Title).Append(sb);
                }
            }

            return(sbmaster.ToString());
        }
        public static string GetBattleDetail(BattleData battle)
        {
            var  sbmaster      = new StringBuilder();
            bool isBaseAirRaid = battle.IsBaseAirRaid;


            foreach (var phase in battle.GetPhases())
            {
                var sb = new StringBuilder();

                switch (phase)
                {
                case PhaseBaseAirRaid p:

                    sb.AppendLine(ConstantsRes.BattleDetail_AirAttackUnits);
                    sb.Append(" ").AppendLine(string.Join(", ", p.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString()).DefaultIfEmpty("(empty)")));

                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseAirBattle p:

                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseBaseAirAttack p:

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_AirAttackWave + "\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine(ConstantsRes.BattleDetail_AirAttackUnits);
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }

                    break;

                case PhaseJetAirBattle p:
                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseJetBaseAirAttack p:

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_AirAttackWave + "\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine(ConstantsRes.BattleDetail_AirAttackUnits);
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }

                    break;

                case PhaseInitial p:


                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine(ConstantsRes.BattleDetail_FriendMainFleet);
                    }
                    else
                    {
                        sb.AppendLine(ConstantsRes.BattleDetail_FriendFleet);
                    }

                    if (isBaseAirRaid)
                    {
                        OutputFriendBase(sb, p.FriendInitialHPs, p.FriendMaxHPs);
                    }
                    else
                    {
                        OutputFriendData(sb, p.FriendFleet, p.FriendInitialHPs, p.FriendMaxHPs);
                    }

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine(ConstantsRes.BattleDetail_FriendEscortFleet);

                        OutputFriendData(sb, p.FriendFleetEscort, p.FriendInitialHPsEscort, p.FriendMaxHPsEscort);
                    }

                    sb.AppendLine();

                    if (p.EnemyMembersEscort != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_EnemyMainFleet);
                    }
                    else
                    {
                        sb.Append(ConstantsRes.BattleDetail_EnemyFleet);
                    }

                    if (p.IsBossDamaged)
                    {
                        sb.Append(" : 装甲破壊");
                    }
                    sb.AppendLine();

                    OutputEnemyData(sb, p.EnemyMembersInstance, p.EnemyLevels, p.EnemyInitialHPs, p.EnemyMaxHPs, p.EnemySlotsInstance, p.EnemyParameters);


                    if (p.EnemyMembersEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine(ConstantsRes.BattleDetail_EnemyEscortFleet);

                        OutputEnemyData(sb, p.EnemyMembersEscortInstance, p.EnemyLevelsEscort, p.EnemyInitialHPsEscort, p.EnemyMaxHPsEscort, p.EnemySlotsEscortInstance, p.EnemyParametersEscort);
                    }

                    sb.AppendLine();

                    if (battle.GetPhases().Where(ph => ph is PhaseBaseAirAttack || ph is PhaseBaseAirRaid).Any(ph => ph != null && ph.IsAvailable))
                    {
                        sb.AppendLine(ConstantsRes.BattleDetail_AirBase);
                        GetBattleDetailBaseAirCorps(sb, KCDatabase.Instance.Battle.Compass.MapAreaID);                                      // :(
                        sb.AppendLine();
                    }

                    if (p.RationIndexes.Length > 0)
                    {
                        sb.AppendLine("〈Combat Ration〉");
                        foreach (var index in p.RationIndexes)
                        {
                            var ship = p.GetFriendShip(index);

                            if (ship != null)
                            {
                                sb.AppendFormat(" {0} #{1}\r\n", ship.NameWithLevel, index + 1);
                            }
                        }
                        sb.AppendLine();
                    }

                    break;

                case PhaseNightInitial p:

                {
                    var eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftFriend];
                    if (eq != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_FriendlyNightContact).AppendLine(eq.Name);
                    }
                    eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftEnemy];
                    if (eq != null)
                    {
                        sb.Append(ConstantsRes.BattleDetail_EnemyNightContact).AppendLine(eq.Name);
                    }
                }

                    {
                        int searchlightIndex = p.SearchlightIndexFriend;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat(ConstantsRes.BattleDetail_FriendlySearchlight + "\r\n", p.FriendFleet.MembersInstance[searchlightIndex].Name, searchlightIndex + 1);
                        }
                        searchlightIndex = p.SearchlightIndexEnemy;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat(ConstantsRes.BattleDetail_EnemySearchlight + "\r\n", p.EnemyMembersInstance[searchlightIndex].NameWithClass, searchlightIndex + 1);
                        }
                    }

                    if (p.FlareIndexFriend != -1)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_FriendlySearchlight + "\r\n", p.FlareFriendInstance.NameWithLevel, p.FlareIndexFriend + 1);
                    }
                    if (p.FlareIndexEnemy != -1)
                    {
                        sb.AppendFormat(ConstantsRes.BattleDetail_EnemySearchlight + "\r\n", p.FlareEnemyInstance.NameWithClass, p.FlareIndexEnemy + 1);
                    }

                    sb.AppendLine();
                    break;


                case PhaseSearching p:
                    sb.Append("Formation: ").Append(Constants.GetFormation(p.FormationFriend));
                    sb.Append(" / Enemy Formation: ").AppendLine(Constants.GetFormation(p.FormationEnemy));
                    sb.Append("Engagement: ").AppendLine(Constants.GetEngagementForm(p.EngagementForm));
                    sb.Append("Contact: ").Append(Constants.GetSearchingResult(p.SearchingFriend));
                    sb.Append(" / Enemy Contact: ").AppendLine(Constants.GetSearchingResult(p.SearchingEnemy));

                    sb.AppendLine();

                    break;

                case PhaseSupport p:
                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈Support Fleet〉");
                        OutputSupportData(sb, p.SupportFleet);
                        sb.AppendLine();
                    }
                    break;

                case PhaseFriendlySupport p:
                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈Friendly Fleet〉");
                        OutputFriendlySupportData(sb, p);
                        sb.AppendLine();

                        {
                            int searchlightIndex = p.SearchlightIndexFriend;
                            if (searchlightIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_FriendlySearchlight + "\r\n", p.SearchlightFriendInstance.NameWithClass, searchlightIndex + 1);
                            }
                            searchlightIndex = p.SearchlightIndexEnemy;
                            if (searchlightIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_EnemySearchlight + "\r\n", p.SearchlightEnemyInstance.NameWithClass, searchlightIndex + 1);
                            }
                        }

                        {
                            int flareIndex = p.FlareIndexFriend;
                            if (flareIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_FriendlyStarshell + "\r\n", p.FlareFriendInstance.NameWithClass, flareIndex + 1);
                            }
                            flareIndex = p.FlareIndexEnemy;
                            if (flareIndex != -1)
                            {
                                sb.AppendFormat(ConstantsRes.BattleDetail_EnemyStarshell + "\r\n", p.FlareEnemyInstance.NameWithClass, flareIndex + 1);
                            }
                        }

                        sb.AppendLine();
                    }
                    break;
                }


                if (!(phase is PhaseBaseAirAttack || phase is PhaseJetBaseAirAttack))                       // 通常出力と重複するため
                {
                    sb.Append(phase.GetBattleDetail());
                }

                if (sb.Length > 0)
                {
                    sbmaster.AppendFormat("== {0} ==\r\n", phase.Title).Append(sb);
                }
            }


            {
                sbmaster.AppendLine(ConstantsRes.BattleDetail_BattleEnd);

                var friend       = battle.Initial.FriendFleet;
                var friendescort = battle.Initial.FriendFleetEscort;
                var enemy        = battle.Initial.EnemyMembersInstance;
                var enemyescort  = battle.Initial.EnemyMembersEscortInstance;

                if (friendescort != null)
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_FriendMainFleet);
                }
                else
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_FriendFleet);
                }

                if (isBaseAirRaid)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (battle.Initial.FriendMaxHPs[i] <= 0)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, string.Format("Base {0}", i + 1),
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < friend.Members.Count(); i++)
                    {
                        var ship = friend.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, ship.Name,
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }

                if (friendescort != null)
                {
                    sbmaster.AppendLine().AppendLine(ConstantsRes.BattleDetail_FriendEscortFleet);

                    for (int i = 0; i < friendescort.Members.Count(); i++)
                    {
                        var ship = friendescort.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.Name,
                                         battle.Initial.FriendInitialHPsEscort[i], battle.ResultHPs[i + 6], battle.Initial.FriendMaxHPsEscort[i]);
                    }
                }


                sbmaster.AppendLine();
                if (enemyescort != null)
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_EnemyMainFleet);
                }
                else
                {
                    sbmaster.AppendLine(ConstantsRes.BattleDetail_EnemyFleet);
                }

                for (int i = 0; i < enemy.Length; i++)
                {
                    var ship = enemy[i];
                    if (ship == null)
                    {
                        continue;
                    }

                    OutputResultData(sbmaster, i,
                                     ship.NameWithClass,
                                     battle.Initial.EnemyInitialHPs[i], battle.ResultHPs[i + 12], battle.Initial.EnemyMaxHPs[i]);
                }

                if (enemyescort != null)
                {
                    sbmaster.AppendLine().AppendLine(ConstantsRes.BattleDetail_EnemyEscortFleet);

                    for (int i = 0; i < enemyescort.Length; i++)
                    {
                        var ship = enemyescort[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.NameWithClass,
                                         battle.Initial.EnemyInitialHPsEscort[i], battle.ResultHPs[i + 18], battle.Initial.EnemyMaxHPsEscort[i]);
                    }
                }

                sbmaster.AppendLine();
            }

            return(sbmaster.ToString());
        }
Пример #5
0
        public static string GetBattleDetail(BattleData battle)
        {
            var  sbmaster      = new StringBuilder();
            bool isBaseAirRaid = battle.IsBaseAirRaid;


            foreach (var phase in battle.GetPhases())
            {
                var sb = new StringBuilder();

                switch (phase)
                {
                case PhaseBaseAirRaid p:

                    sb.AppendLine("味方基地航空隊 参加中隊:");
                    sb.Append(" ").AppendLine(string.Join(", ", p.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString()).DefaultIfEmpty("(なし)")));

                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseAirBattle p:

                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseBaseAirAttack p:

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat("〈第{0}波〉\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine("味方基地航空隊 参加中隊:");
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }

                    break;

                case PhaseJetAirBattle p:
                    GetBattleDetailPhaseAirBattle(sb, p);

                    break;

                case PhaseJetBaseAirAttack p:

                    foreach (var a in p.AirAttackUnits)
                    {
                        sb.AppendFormat("〈第{0}波〉\r\n", a.AirAttackIndex + 1);

                        sb.AppendLine("味方基地航空隊 参加中隊:");
                        sb.Append(" ").AppendLine(string.Join(", ", a.Squadrons.Where(sq => sq.EquipmentInstance != null).Select(sq => sq.ToString())));

                        GetBattleDetailPhaseAirBattle(sb, a);
                        sb.Append(a.GetBattleDetail());
                    }

                    break;

                case PhaseInitial p:


                    if (p.FriendFleetEscort != null)
                    {
                        sb.Append("〈味方主力艦隊〉");
                    }
                    else
                    {
                        sb.Append("〈味方艦隊〉");
                    }


                    void appendFleetInfo(FleetData fleet)
                    {
                        sb.Append(" 制空戦力 ");
                        sb.Append(GetRangeString(Calculator.GetAirSuperiority(fleet, false), Calculator.GetAirSuperiority(fleet, true)));

                        double truncate2(double value) => Math.Floor(value * 100) / 100;

                        sb.AppendFormat(" / 索敵能力 [1] {0}, [2] {1}, [3] {2}, [4] {3}",
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 1)),
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 2)),
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 3)),
                                        truncate2(Calculator.GetSearchingAbility_New33(fleet, 4)));
                    }

                    if (isBaseAirRaid)
                    {
                        sb.AppendLine();
                        OutputFriendBase(sb, p.FriendInitialHPs, p.FriendMaxHPs);
                    }
                    else
                    {
                        appendFleetInfo(p.FriendFleet);
                        sb.AppendLine();
                        OutputFriendData(sb, p.FriendFleet, p.FriendInitialHPs, p.FriendMaxHPs);
                    }

                    if (p.FriendFleetEscort != null)
                    {
                        sb.AppendLine();
                        sb.Append("〈味方随伴艦隊〉");
                        appendFleetInfo(p.FriendFleetEscort);
                        sb.AppendLine();

                        OutputFriendData(sb, p.FriendFleetEscort, p.FriendInitialHPsEscort, p.FriendMaxHPsEscort);
                    }

                    sb.AppendLine();

                    if (p.EnemyMembersEscort != null)
                    {
                        sb.Append("〈敵主力艦隊〉");
                    }
                    else
                    {
                        sb.Append("〈敵艦隊〉");
                    }

                    if (p.IsBossDamaged)
                    {
                        sb.Append(" : 装甲破壊");
                    }
                    sb.AppendLine();

                    OutputEnemyData(sb, p.EnemyMembersInstance, p.EnemyLevels, p.EnemyInitialHPs, p.EnemyMaxHPs, p.EnemySlotsInstance, p.EnemyParameters);


                    if (p.EnemyMembersEscort != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("〈敵随伴艦隊〉");

                        OutputEnemyData(sb, p.EnemyMembersEscortInstance, p.EnemyLevelsEscort, p.EnemyInitialHPsEscort, p.EnemyMaxHPsEscort, p.EnemySlotsEscortInstance, p.EnemyParametersEscort);
                    }

                    sb.AppendLine();

                    if (battle.GetPhases().Where(ph => ph is PhaseBaseAirAttack || ph is PhaseBaseAirRaid).Any(ph => ph != null && ph.IsAvailable))
                    {
                        sb.AppendLine("〈基地航空隊〉");
                        GetBattleDetailBaseAirCorps(sb, KCDatabase.Instance.Battle.Compass.MapAreaID);                                      // :(
                        sb.AppendLine();
                    }

                    if (p.RationIndexes.Length > 0)
                    {
                        sb.AppendLine("〈戦闘糧食補給〉");
                        foreach (var index in p.RationIndexes)
                        {
                            var ship = p.GetFriendShip(index);

                            if (ship != null)
                            {
                                sb.AppendFormat(" {0} #{1}\r\n", ship.NameWithLevel, index + 1);
                            }
                        }
                        sb.AppendLine();
                    }

                    break;

                case PhaseNightInitial p:

                {
                    var eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftFriend];
                    if (eq != null)
                    {
                        sb.Append("自軍夜間触接: ").AppendLine(eq.Name);
                    }
                    eq = KCDatabase.Instance.MasterEquipments[p.TouchAircraftEnemy];
                    if (eq != null)
                    {
                        sb.Append("敵軍夜間触接: ").AppendLine(eq.Name);
                    }
                }

                    {
                        int searchlightIndex = p.SearchlightIndexFriend;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat("自軍探照灯照射: {0} #{1}\r\n", p.FriendFleet.MembersInstance[searchlightIndex].Name, searchlightIndex + 1);
                        }
                        searchlightIndex = p.SearchlightIndexEnemy;
                        if (searchlightIndex != -1)
                        {
                            sb.AppendFormat("敵軍探照灯照射: {0} #{1}\r\n", p.EnemyMembersInstance[searchlightIndex].NameWithClass, searchlightIndex + 1);
                        }
                    }

                    if (p.FlareIndexFriend != -1)
                    {
                        sb.AppendFormat("自軍照明弾投射: {0} #{1}\r\n", p.FlareFriendInstance.NameWithLevel, p.FlareIndexFriend + 1);
                    }
                    if (p.FlareIndexEnemy != -1)
                    {
                        sb.AppendFormat("敵軍照明弾投射: {0} #{1}\r\n", p.FlareEnemyInstance.NameWithClass, p.FlareIndexEnemy + 1);
                    }

                    sb.AppendLine();
                    break;


                case PhaseSearching p:
                    sb.Append("自軍陣形: ").Append(Constants.GetFormation(p.FormationFriend));
                    sb.Append(" / 敵軍陣形: ").AppendLine(Constants.GetFormation(p.FormationEnemy));
                    sb.Append("交戦形態: ").AppendLine(Constants.GetEngagementForm(p.EngagementForm));
                    sb.Append("自軍索敵: ").Append(Constants.GetSearchingResult(p.SearchingFriend));
                    sb.Append(" / 敵軍索敵: ").AppendLine(Constants.GetSearchingResult(p.SearchingEnemy));

                    sb.AppendLine();

                    break;

                case PhaseSupport p:
                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈支援艦隊〉");
                        OutputSupportData(sb, p.SupportFleet);
                        sb.AppendLine();
                    }
                    break;

                case PhaseFriendlySupport p:
                    if (p.IsAvailable)
                    {
                        sb.AppendLine("〈友軍艦隊〉");
                        OutputFriendlySupportData(sb, p);
                        sb.AppendLine();

                        {
                            int searchlightIndex = p.SearchlightIndexFriend;
                            if (searchlightIndex != -1)
                            {
                                sb.AppendFormat("自軍探照灯照射: {0} #{1}\r\n", p.SearchlightFriendInstance.NameWithClass, searchlightIndex + 1);
                            }
                            searchlightIndex = p.SearchlightIndexEnemy;
                            if (searchlightIndex != -1)
                            {
                                sb.AppendFormat("敵軍探照灯照射: {0} #{1}\r\n", p.SearchlightEnemyInstance.NameWithClass, searchlightIndex + 1);
                            }
                        }

                        {
                            int flareIndex = p.FlareIndexFriend;
                            if (flareIndex != -1)
                            {
                                sb.AppendFormat("自軍照明弾投射: {0} #{1}\r\n", p.FlareFriendInstance.NameWithClass, flareIndex + 1);
                            }
                            flareIndex = p.FlareIndexEnemy;
                            if (flareIndex != -1)
                            {
                                sb.AppendFormat("敵軍照明弾投射: {0} #{1}\r\n", p.FlareEnemyInstance.NameWithClass, flareIndex + 1);
                            }
                        }

                        sb.AppendLine();
                    }
                    break;
                }


                if (!(phase is PhaseBaseAirAttack || phase is PhaseJetBaseAirAttack))                       // 通常出力と重複するため
                {
                    sb.Append(phase.GetBattleDetail());
                }

                if (sb.Length > 0)
                {
                    sbmaster.AppendFormat("《{0}》\r\n", phase.Title).Append(sb);
                }
            }


            {
                sbmaster.AppendLine("《戦闘終了》");

                var friend       = battle.Initial.FriendFleet;
                var friendescort = battle.Initial.FriendFleetEscort;
                var enemy        = battle.Initial.EnemyMembersInstance;
                var enemyescort  = battle.Initial.EnemyMembersEscortInstance;

                if (friendescort != null)
                {
                    sbmaster.AppendLine("〈味方主力艦隊〉");
                }
                else
                {
                    sbmaster.AppendLine("〈味方艦隊〉");
                }

                if (isBaseAirRaid)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        if (battle.Initial.FriendMaxHPs[i] <= 0)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, string.Format("第{0}基地", i + 1),
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < friend.Members.Count(); i++)
                    {
                        var ship = friend.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i, ship.Name,
                                         battle.Initial.FriendInitialHPs[i], battle.ResultHPs[i], battle.Initial.FriendMaxHPs[i]);
                    }
                }

                if (friendescort != null)
                {
                    sbmaster.AppendLine().AppendLine("〈味方随伴艦隊〉");

                    for (int i = 0; i < friendescort.Members.Count(); i++)
                    {
                        var ship = friendescort.MembersInstance[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.Name,
                                         battle.Initial.FriendInitialHPsEscort[i], battle.ResultHPs[i + 6], battle.Initial.FriendMaxHPsEscort[i]);
                    }
                }


                sbmaster.AppendLine();
                if (enemyescort != null)
                {
                    sbmaster.AppendLine("〈敵主力艦隊〉");
                }
                else
                {
                    sbmaster.AppendLine("〈敵艦隊〉");
                }

                for (int i = 0; i < enemy.Length; i++)
                {
                    var ship = enemy[i];
                    if (ship == null)
                    {
                        continue;
                    }

                    OutputResultData(sbmaster, i,
                                     ship.NameWithClass,
                                     battle.Initial.EnemyInitialHPs[i], battle.ResultHPs[i + 12], battle.Initial.EnemyMaxHPs[i]);
                }

                if (enemyescort != null)
                {
                    sbmaster.AppendLine().AppendLine("〈敵随伴艦隊〉");

                    for (int i = 0; i < enemyescort.Length; i++)
                    {
                        var ship = enemyescort[i];
                        if (ship == null)
                        {
                            continue;
                        }

                        OutputResultData(sbmaster, i + 6, ship.NameWithClass,
                                         battle.Initial.EnemyInitialHPsEscort[i], battle.ResultHPs[i + 18], battle.Initial.EnemyMaxHPsEscort[i]);
                    }
                }

                sbmaster.AppendLine();
            }

            return(sbmaster.ToString());
        }