From 8c63e748380f330fd46bd0aefeaecf216f0d26c1 Mon Sep 17 00:00:00 2001 From: RadarNyan Date: Wed, 20 Dec 2017 10:34:23 +0900 Subject: [PATCH 01/12] =?UTF-8?q?=E3=82=B0=E3=83=AB=E3=83=BC=E3=83=97?= =?UTF-8?q?=EF=BC=9A=E3=80=8C=E3=81=A7=E7=B5=82=E3=82=8F=E3=82=8B=E3=80=8D?= =?UTF-8?q?=E3=83=BB=E3=80=8C=E3=81=A7=E7=B5=82=E3=82=8F=E3=82=89=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=80=8D=E6=9D=A1=E4=BB=B6=E3=82=92=E5=90=AB=E3=82=80?= =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=AB=E3=82=BF=E3=81=8C=E8=AA=A4=E5=8B=95?= =?UTF-8?q?=E4=BD=9C=E3=81=97=E3=81=AA=E3=81=84=E3=82=88=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/ShipGroup/ExpressionData.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/ElectronicObserver/Data/ShipGroup/ExpressionData.cs b/ElectronicObserver/Data/ShipGroup/ExpressionData.cs index 62676aa8d..921926d98 100644 --- a/ElectronicObserver/Data/ShipGroup/ExpressionData.cs +++ b/ElectronicObserver/Data/ShipGroup/ExpressionData.cs @@ -255,20 +255,16 @@ public Expression Compile(ParameterExpression paramex) condex = Expression.Not(Expression.Call(memberex, typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), constex)); break; case ExpressionOperator.BeginWith: - condex = Expression.Equal(Expression.Call(memberex, typeof(string).GetMethod("IndexOf", new Type[] { typeof(string) }), constex), Expression.Constant(0, typeof(int))); + condex = Expression.Call(memberex, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), constex); break; case ExpressionOperator.NotBeginWith: - condex = Expression.NotEqual(Expression.Call(memberex, typeof(string).GetMethod("IndexOf", new Type[] { typeof(string) }), constex), Expression.Constant(0, typeof(int))); + condex = Expression.Not(Expression.Call(memberex, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), constex)); break; - case ExpressionOperator.EndWith: // returns memberex.LastIndexOf( constex ) == ( memberex.Length - constex.Length ) - condex = Expression.Equal( - Expression.Call(memberex, typeof(string).GetMethod("LastIndexOf", new Type[] { typeof(string) }), constex), - Expression.Subtract(Expression.PropertyOrField(memberex, "Length"), Expression.PropertyOrField(constex, "Length"))); + case ExpressionOperator.EndWith: + condex = Expression.Call(memberex, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), constex); break; - case ExpressionOperator.NotEndWith: // returns memberex.LastIndexOf( constex ) != ( memberex.Length - constex.Length ) - condex = Expression.NotEqual( - Expression.Call(memberex, typeof(string).GetMethod("LastIndexOf", new Type[] { typeof(string) }), constex), - Expression.Subtract(Expression.PropertyOrField(memberex, "Length"), Expression.PropertyOrField(constex, "Length"))); + case ExpressionOperator.NotEndWith: + condex = Expression.Not(Expression.Call(memberex, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), constex)); break; case ExpressionOperator.ArrayContains: // returns Enumerable.Contains<>( memberex ) condex = Expression.Call(typeof(Enumerable), "Contains", new Type[] { memberex.Type.GetElementType() ?? memberex.Type.GetGenericArguments().First() }, memberex, constex); From 692df399aec85bf8f98b3af2f3cfa4f3496ad0ca Mon Sep 17 00:00:00 2001 From: RadarNyan Date: Tue, 26 Dec 2017 18:28:37 +0900 Subject: [PATCH 02/12] =?UTF-8?q?=E8=B3=87=E6=BA=90=E3=83=81=E3=83=A3?= =?UTF-8?q?=E3=83=BC=E3=83=88=EF=BC=9A=E8=B3=87=E6=BA=90=E3=80=81=E8=B3=87?= =?UTF-8?q?=E6=BA=90(=E5=B7=AE=E5=88=86)=E3=83=81=E3=83=A3=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=AB=E9=AB=98=E9=80=9F=E4=BF=AE=E5=BE=A9=E6=9D=90?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Window/Dialog/DialogResourceChart.cs | 67 ++++++++++++------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/ElectronicObserver/Window/Dialog/DialogResourceChart.cs b/ElectronicObserver/Window/Dialog/DialogResourceChart.cs index 22ed4b3c5..c93fefa6d 100644 --- a/ElectronicObserver/Window/Dialog/DialogResourceChart.cs +++ b/ElectronicObserver/Window/Dialog/DialogResourceChart.cs @@ -98,6 +98,7 @@ private void SetResourceChart() var area = ResourceChart.ChartAreas.Add("ResourceChartArea"); area.AxisX = CreateAxisX(SelectedChartSpan); area.AxisY = CreateAxisY(2000); + area.AxisY2 = CreateAxisY(200); ResourceChart.Legends.Clear(); var legend = ResourceChart.Legends.Add("ResourceLegend"); @@ -110,6 +111,7 @@ private void SetResourceChart() var ammo = ResourceChart.Series.Add("ResourceSeries_Ammo"); var steel = ResourceChart.Series.Add("ResourceSeries_Steel"); var bauxite = ResourceChart.Series.Add("ResourceSeries_Bauxite"); + var instantRepair = ResourceChart.Series.Add("ResourceSeries_InstantRepair"); var setSeries = new Action(s => { @@ -134,6 +136,11 @@ private void SetResourceChart() bauxite.Color = Color.FromArgb(255, 0, 0); bauxite.LegendText = "ボーキ"; + setSeries(instantRepair); + instantRepair.Color = Color.FromArgb(32, 128, 255); + instantRepair.LegendText = "高速修復材"; + instantRepair.YAxisType = AxisType.Secondary; + //データ設定 { @@ -152,20 +159,11 @@ private void SetResourceChart() ammo.Points.AddXY(r.Date.ToOADate(), r.Ammo); steel.Points.AddXY(r.Date.ToOADate(), r.Steel); bauxite.Points.AddXY(r.Date.ToOADate(), r.Bauxite); + instantRepair.Points.AddXY(r.Date.ToOADate(), r.InstantRepair); prev = r; } } - - - if (fuel.Points.Count > 0) - { - int min = (int)new[] { fuel.Points.Min(p => p.YValues[0]), ammo.Points.Min(p => p.YValues[0]), steel.Points.Min(p => p.YValues[0]), bauxite.Points.Min(p => p.YValues[0]) }.Min(); - area.AxisY.Minimum = Math.Floor(min / 10000.0) * 10000; - - int max = (int)new[] { fuel.Points.Max(p => p.YValues[0]), ammo.Points.Max(p => p.YValues[0]), steel.Points.Max(p => p.YValues[0]), bauxite.Points.Max(p => p.YValues[0]) }.Max(); - area.AxisY.Maximum = Math.Ceiling(max / 10000.0) * 10000; - } } @@ -180,6 +178,7 @@ private void SetResourceDiffChart() var area = ResourceChart.ChartAreas.Add("ResourceChartArea"); area.AxisX = CreateAxisX(SelectedChartSpan); area.AxisY = CreateAxisY(200); + area.AxisY2 = CreateAxisY(20); ResourceChart.Legends.Clear(); var legend = ResourceChart.Legends.Add("ResourceLegend"); @@ -192,6 +191,7 @@ private void SetResourceDiffChart() var ammo = ResourceChart.Series.Add("ResourceSeries_Ammo"); var steel = ResourceChart.Series.Add("ResourceSeries_Steel"); var bauxite = ResourceChart.Series.Add("ResourceSeries_Bauxite"); + var instantRepair = ResourceChart.Series.Add("ResourceSeries_InstantRepair"); var setSeries = new Action(s => { @@ -222,6 +222,12 @@ private void SetResourceDiffChart() bauxite.BorderColor = Color.FromArgb(255, 255, 0, 0); bauxite.LegendText = "ボーキ"; + setSeries(instantRepair); + instantRepair.Color = Color.FromArgb(64, 32, 128, 255); + instantRepair.BorderColor = Color.FromArgb(255, 32, 128, 255); + instantRepair.LegendText = "高速修復材"; + instantRepair.YAxisType = AxisType.Secondary; + //データ設定 { @@ -238,7 +244,13 @@ private void SetResourceDiffChart() if (ShouldSkipRecord(r.Date - prev.Date)) continue; - double[] ys = new double[] { r.Fuel - prev.Fuel, r.Ammo - prev.Ammo, r.Steel - prev.Steel, r.Bauxite - prev.Bauxite }; + double[] ys = new double[] { + r.Fuel - prev.Fuel, + r.Ammo - prev.Ammo, + r.Steel - prev.Steel, + r.Bauxite - prev.Bauxite, + r.InstantRepair - prev.InstantRepair }; + if (Menu_Option_DivideByDay.Checked) { for (int i = 0; i < 4; i++) @@ -249,26 +261,18 @@ private void SetResourceDiffChart() ammo.Points.AddXY(prev.Date.ToOADate(), ys[1]); steel.Points.AddXY(prev.Date.ToOADate(), ys[2]); bauxite.Points.AddXY(prev.Date.ToOADate(), ys[3]); + instantRepair.Points.AddXY(prev.Date.ToOADate(), ys[4]); fuel.Points.AddXY(r.Date.ToOADate(), ys[0]); ammo.Points.AddXY(r.Date.ToOADate(), ys[1]); steel.Points.AddXY(r.Date.ToOADate(), ys[2]); bauxite.Points.AddXY(r.Date.ToOADate(), ys[3]); + instantRepair.Points.AddXY(r.Date.ToOADate(), ys[4]); prev = r; } } - - - if (fuel.Points.Count > 0) - { - int min = (int)new[] { fuel.Points.Min(p => p.YValues[0]), ammo.Points.Min(p => p.YValues[0]), steel.Points.Min(p => p.YValues[0]), bauxite.Points.Min(p => p.YValues[0]) }.Min(); - area.AxisY.Minimum = Math.Floor(min / 1000.0) * 1000; - - int max = (int)new[] { fuel.Points.Max(p => p.YValues[0]), ammo.Points.Max(p => p.YValues[0]), steel.Points.Max(p => p.YValues[0]), bauxite.Points.Max(p => p.YValues[0]) }.Max(); - area.AxisY.Maximum = Math.Ceiling(max / 1000.0) * 1000; - } } @@ -887,13 +891,30 @@ private void SetYBounds(double min, double max) ResourceChart.ChartAreas[0].AxisY.Interval = unit; ResourceChart.ChartAreas[0].AxisY.MinorGrid.Interval = unit / 2; + if (ResourceChart.Series.Where(s => s.Enabled).Any(s => s.YAxisType == AxisType.Secondary)) { + ResourceChart.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True; + if (ResourceChart.Series.Count(s => s.Enabled) == 1) { + ResourceChart.ChartAreas[0].AxisY2.MajorGrid.Enabled = true; + ResourceChart.ChartAreas[0].AxisY2.MinorGrid.Enabled = true; + } else { + ResourceChart.ChartAreas[0].AxisY2.MajorGrid.Enabled = false; + ResourceChart.ChartAreas[0].AxisY2.MinorGrid.Enabled = false; + } + ResourceChart.ChartAreas[0].AxisY2.Minimum = ResourceChart.ChartAreas[0].AxisY.Minimum / 100; + ResourceChart.ChartAreas[0].AxisY2.Maximum = ResourceChart.ChartAreas[0].AxisY.Maximum / 100; + ResourceChart.ChartAreas[0].AxisY2.Interval = unit / 100; + ResourceChart.ChartAreas[0].AxisY2.MinorGrid.Interval = unit / 200; + } else { + ResourceChart.ChartAreas[0].AxisY2.Enabled = AxisEnabled.False; + } + } private void SetYBounds() { SetYBounds( - !ResourceChart.Series.Any(s => s.Enabled) || SelectedChartType == ChartType.ExperienceDiff ? 0 : ResourceChart.Series.Where(s => s.Enabled).Select(s => s.Points.Min(p => p.YValues[0])).Min(), - !ResourceChart.Series.Any(s => s.Enabled) ? 0 : ResourceChart.Series.Where(s => s.Enabled).Select(s => s.Points.Max(p => p.YValues[0])).Max() + !ResourceChart.Series.Any(s => s.Enabled) || SelectedChartType == ChartType.ExperienceDiff ? 0 : ResourceChart.Series.Where(s => s.Enabled).Select(s => s.YAxisType == AxisType.Secondary ? s.Points.Min(p => p.YValues[0] * 100) : s.Points.Min(p => p.YValues[0])).Min(), + !ResourceChart.Series.Any(s => s.Enabled) ? 0 : ResourceChart.Series.Where(s => s.Enabled).Select(s => s.YAxisType == AxisType.Secondary ? s.Points.Max(p => p.YValues[0] * 100) : s.Points.Max(p => p.YValues[0])).Max() ); } From 77cb9402a140fbe28abcf9054b64eaa223f09dc5 Mon Sep 17 00:00:00 2001 From: RadarNyan Date: Thu, 28 Dec 2017 14:49:29 +0900 Subject: [PATCH 03/12] =?UTF-8?q?=E6=88=A6=E9=97=98=E8=A9=B3=E7=B4=B0?= =?UTF-8?q?=EF=BC=9A=E6=94=BB=E6=92=83=E6=96=B9=E5=90=91=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=81=A8=E3=81=8D=E3=80=81=E5=91=B3=E6=96=B9?= =?UTF-8?q?=E8=89=A6=E3=82=92=E5=B7=A6=E5=81=B4=E3=81=AB=E7=BD=AE=E3=81=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 航空戦・支援攻撃には変化なし --- ElectronicObserver/Data/Battle/Detail/BattleDetail.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs b/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs index d8e43dd77..bc9757a96 100644 --- a/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs +++ b/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs @@ -149,7 +149,11 @@ public override string ToString() StringBuilder builder = new StringBuilder(); - builder.AppendFormat("{0} → {1}\r\n", GetAttackerName(), GetDefenderName()); + // 航空戦・支援攻撃時 AttackerIndex = BattleIndex.Invalid 、それで AttackerIndex.Side = BattleSides.FriendMain になる + // DefenderIndex.Side で判断すれば航空戦も正確に識別できるが表示が変になるので、最終的には AttackerIndex.Side で判断しだ + bool attackerIsFriend = AttackerIndex.Side == BattleSides.FriendMain || AttackerIndex.Side == BattleSides.FriendEscort; + + builder.AppendFormat(attackerIsFriend ? "{0} → {1}\r\n" : "{1} ← {0}\r\n", GetAttackerName(), GetDefenderName()); if (AttackType >= 0) From 4bfeae0601121386fcd507af211c82f7776229be Mon Sep 17 00:00:00 2001 From: Andante Date: Sat, 30 Dec 2017 05:24:18 +0900 Subject: [PATCH 04/12] =?UTF-8?q?=E6=96=B0=E8=A6=81=E7=B4=A0=E3=81=B8?= =?UTF-8?q?=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 局地戦闘機の改修による制空値補正に対応 * 戦闘詳報による改装に対応 * 戦闘詳報のアイコンを追加 * 長波改二の主雷電カットインのD型砲火力補正に対応 * D型砲(+水上電探)による特殊パラメータ補正に対応 * 艦船図鑑:艦型を表示・記録するように --- ElectronicObserver/Assets.zip | Bin 205497 -> 205930 bytes .../Assets/Item/ActionReport.png | Bin 0 -> 278 bytes ElectronicObserver/Data/Constants.cs | 2088 ++++++------ ElectronicObserver/Data/ShipData.cs | 2869 ++++++++-------- ElectronicObserver/Data/ShipDataMaster.cs | 10 + .../Observer/kcsapi/api_start2.cs | 1 + .../Other/Information/apilist.txt | 1 + .../Other/Information/kcmemo.md | 64 +- .../Resource/ResourceManager.cs | 4 +- ElectronicObserver/Utility/Data/Calculator.cs | 3 +- .../Window/Dialog/DialogAlbumMasterShip.cs | 2906 +++++++++-------- 11 files changed, 4076 insertions(+), 3870 deletions(-) create mode 100644 ElectronicObserver/Assets/Item/ActionReport.png diff --git a/ElectronicObserver/Assets.zip b/ElectronicObserver/Assets.zip index 331c3feb083a7abeb95b8ca043c6f049ebe219be..4c52bd619aa9eb62df5f905da923d5416d3a740b 100644 GIT binary patch delta 5635 zcmZ{o30PLe8pru&(hy`6m*YnuA7)BEQ9NntM=Xg8t9b!SMF9~-6csnDyy?}_&``57 zeO%>Ns2m%8xq{LcBkGw-}JXU@kt-@b#b zs|s7Y#YFRmT%63Gv@RQVxuphkNjm-^v*s@g?$W|M%iq<1j+=R~V)_Vcend=nXJx04 z*xXB5_Zn-y|I)n94^C>gPZO%i#LuSss)N#sHH=?spOgP`B_ZTq^HN*YLFS|=XNyZg zp2d=3m`aUa(A#R6;{M>2zUpCdXRAC4PV}%Weo`JR8adojFmgEaebQ`Guy7%pp~@;~ zSjvj6%E?K*Y*9y%TiF-w)X~GAvteSzoUfgqC~BV*-D_pZTdgckPKNyRl1mUeb7pGh zO#jHt)G7X2gC&4^2#Hg(2|T?=}wI=~)nwLI_r^@VY~+n^OwKlYusBPh{pfZq^b z--vNu*X=_mtghWZ@95K|nFn(VU2~s)ddRyK7YF9dy&17>Qfh5zz}`MaO`p=Lo%=uP z6;k%XsT1~%P6s?s9Z#G7ea6bns~!6U9Xe87IyvU_oNw(vRPTsbveoi7EHO-RRbEt*KM!snbp&m3lf;xTSlaggR7 zX7S>?U^tL2n{M$da3Dn&v3T3x^5Ha_7nf}1o^-K@c^fVVo>il0&I$@JD{Oa!jW-Tu zo5#f#O-F_Agji|I5f<)t9$}$Kjk1eK_eDC8GQO8?&n!5QDy6gO;WV2Un0AysYph=# ztj5=D=oVRg<;1jZjN4laukhYwV?XD-nf#iOYCE0ZSn$0Ks)=3s* zyb=DKDpd209flTWj;BFeQNN>ilr({i-E@o*qTo{?2G zY=r}<;0#L_akX$D`Ja{T)(;F-`9RummQ655&x6x+T(9yZEA=`jS7GN-#6f!f92+D4 z?%ZGH0jcJktScoQ4y42qHbr#%5Dui05;jS^aT^Y#*z;_%==szDl@FvN=Vkqi=D>k8 z;DT(IRsaXmR~KacEpEYSI_e)h(Mm&0S(qsF8>n)Fw6#=T@knCc7C7Z=%7(K!|l zBzpy$YW(A$aGH)ejmfmqnF=;YxO5Cxc|dynk{qx9SUB*(HWqZ~66+;eT;kd9Q!-StLtr0NS&z>jiedar{6DfdUY zg1zp+fn;2kE4?^6O7#V4!DW^vj;w(Lss6GYxAS#4kTR~w`pO=SR((M#zan?VxvBCjeQ;-k)OejuGNxs~X*%jUnQf&NH&{QL{uIze{J;PBZrxyZ!|oiT3f0W0Gm}!k zD*3V5yXO!U18KYIvggBr)UH~(xs`Ary(*ne=hJLH_}yw|_s)5Ls2V`iHyy>G@w>TJ z8v7Fq7eTk7LHg_``SI=hVyx;4Qk$F1n?iqPA)sz@ZuhK&ty$ZWWJy zaViT)<9?B|>9z?Dq@%yct#`f*4x|&cGHJrEEJ$Q^!VEwJ4*bf3MPwWTpjlsvO;1y^ z`I@|all3(QuN#n>zCM<#j&1*D5>^=hruJq)7)TNg76w}*|Q2jv~Q!B^$E(s1aS3O>A zUIPbG-#U5M*Ia`GDX-3)bDwyX52T;#<)yUO%YRO9E<^yNMfI|%%2RNl*?73I)@`Ip zpoyy}9|x^8qk-AQ?NNw>X2ITcwn0884$egYBwM4L$%cA35RLO1*>j>X4BG&t2HDuA zw}fW%{WJSF_M8zhKS7nJ=~rhaqGP|wbq^0i45ZNCS+Y&H)BIyn`8q=1{4O_T;^LOy z7s-vMx$&5ph}`bU4cO?Fs0IY-m3u6~*f$(b)3HYHT(J_nFYoAfTM!3n_F8stveH$vPgnmWH4aFDO>+4zPJ{y~w@Kcs+dhB;tfiK84eCtlY;9a|i*MicD9r1P-K-mNNH%3vil_-0SaI=~PRZJL_>Q8%W(BmU-r8!-2HcbcagdK=YAe znC$}#-b*x_T^5p$+n$u;%)5BUhEG&8(2N{1PMxC%?X*~|bk~^&ibMMm04byuA0x8v z!-4dX=}HEtsstc;x$smGyABSd?8 zgafJ3jVB7D_XIT{NU4G+iMmyAAe}Vbxq3K|g4^(9n_gzk<`+i2m7Z(Ey^XHvlhr7i zd%rX<6uGwLqlDp_jtUeh({#rM!GTn6y4CaHKnio0F5(L~kUnvjvs~M1lFA2?M>{@J zEFK64(rfL^zFXixsxsY&ci=!8+MdUYM1Rx{(&z1Yf=$mu^Dk!}(}8<;FI_%GRinAK z0@=``gZ!$**=dyrz1M*c=|0!b#1P-JrkMPN2VEY+rAds#-!qdgW zL*PIf?J4tpw-^qjvz{{FYy06qiuRIy``w2FX}=erVAJ(!HlIvXXFkB#vtyPjL=&rm zN8NvS=8@v#Gng$%R&QAWe=JjV0%@7)4ky8Z#BB2O*!B?|NH5uBrBi-`1L+sD-RwjZ z0aA(&ANQxiP(5wjFSpDcA3n&)?}oQBO-F+h2V{e^E_|Q3Q-xPPke+&!r_Sqr0WYeW z=!6^T&)-BoW_}+le|+TMs6zJtzL(5=YFb8`i)!WMWO1@OMdrljn@=)%;@SUUOvmUJ TEzN|*@^|k@C#RglOrHG*R;EPe delta 5328 zcmZvgdstOf8izS+c|k6VtGk29Ip7U#M$JoEB5Ep@p$=wAat9Sfy!NO~c^Ncy$gonB zZ^r3qYP^(piD^h}nn~2MArE*IHBdsO3_?W(6%}Uf^*f7vc+x-Kz2Eh%Z+&a6z4zJd zns2-g9`o{!iRSG*+{}Mvak2T{Ga~t!xL9&*XV!xCkzwu4vx59l%e>8l+=Z`LDbC3} z3SNxq>dtTaFD_X4%GN=u$*4W{43*fl!DhTkx&PI z^-Fxs1C{s%cZ)~i9*bq3VJcNZ;geR&Tt6=QEK;ZR?>-hk*3qr7q>m-LuRQp3T&$%q zE|!J&HM*0S4a19nA56` zJGMtVEt=;Cjy$({0;5PC1am|0mr{?-!H< z=^g3pdGTkzIX+ZMI!BpYfZN6l8rG+)19CZeX3EZ*4v zyJ@OT6A5znjj__34mLuJPe(gQB@UJ#-madd`hYaFge8g0!5PYdw4;Qj3a|NaAayQf ziDL6kIFPbRS-jYK84jeM&A1p()C|%~r&y9**RR=jvZbfkFvC%qsS45LS!N>Y?qt)& zwnIn?(xgt@Mh~i(ps$>4kcetPD@g1#OA%H5kqx8;r{z@bE8sw?IL*@RV~gQ5A1zJZ zb|gy+razuxVaD4%503AV=Co)o>N3ZyZ~qxKP5fh)dF-@+6j~-ni{1(cQcjtyYH>Xr zNKIvIwz2B?Jk?jzwUK{Mu+qk}Y@{geJzuqh^ut*;OJprtpd3gmJ$L|RoMRKk$Rad= zbnKkm&8mlRAPqh*i}M-3P$dBA!}Dye$X*KvQt)Dd7T}Atqde1IclL zC5ynKH&i~5hFz3Xo9MSxIgmcNDEH@9G#p4ll``LZYvDl3sg&a`-|;8a7o_G&HeYnB zf&*#k4{W~iad4K3({$}w>LM#yt5}qH?$b9_J4l&Ta=Z<0tCa&=uia+hkPexyVLu#5eJ)G)pau@4zg(7!JiO-`H4sSRioEdVCTvg+q-9s+qWBXWNOf1_ z;*G3^18HitT;x^j^Hg7uj#smp;y^hZND)8EaVrf{aUkXYDC}~Qht`>UZU;Ff#mpE zuEE+GBE%LV`rj~^m+t!~z z6)p~0ZuX=%YvptDpgmu;f%J>%vafxn97r$!BHi7WzElpRFQv1$&HI}bOs-=gwh6~7 zRd3BDcO2>*JvQ#L(vCXzoY+uSrZhsX>u)Z?sjnyzK=DKu#HH8xz#Oh!9MCD-JS zNxLm@APv1PFO_~*;XwNMx|~$XQ|DA}kbG~*OYh+VIFMG}U~!_lH_8W1XQPhwEYesv z4Go&D#aZdqdN#_g=d0Ovg`D+lh_UQDAN9haX$k*9Rz;yVS(^AN+dOt!Kzi?{{25Cu zf&=Nk85h@hMa6-Xc}vdDGpbrSkWSxXDaOtNHOgta3SRLaE2Z6LL&fE0w1c$kw#-x5 zt5)>^DWE~Rf>bz=mNm!=d&rm@Dh{OD2KfYSD!Hc|NXd=z=IL#3QVukC%tkjF<={zE z(Ew7Ch5w$W-(dqqyJIb?2S}y&Wsf6w*l6)ofSX!65F0b#E{hQ56VL$C8+YY{!M{%@ z6%5k#yYj|6u?`NTCz@pDrT5sgV%{+{fb{J>_KJ9GtWXI+GdNa!y$KF9-w16~&?F}_ z%YgLp7Z2D7 zWB0^BRkG&3U|)Goeh=k7yzYiJkXAorDRv#F`Djw}g`79b3%2(Xn@XyA{(UnM#Wc%G zJJup8NQax{?daGMq~byI=^K#yeziA6wa9z^;cYa6w53H}Ngwp@qB?+^JMo#KcsUff zc?C}ui#~?}H`noL!tWLoXkI}{c3q`r+bPNC8@46 zft25#ryE`S^;CT|T^H28dsd3-z{iTCv(OHjeFA7t2R>OGt_xQkLGtd%)5RA@dn*Uh zO4E(-#NvR|V7l5UIFK^jrOU~J1L=b4^n!xstHl(1NXU3~J8QPx5%pqQ)rp50YkZzm z)o8|d>L<_1>cQj1nppGLX#vd_%~bLDMmUgenC@gT97xHYe1`BH)nD}m>69nW5HZ6B zDhJXyFP>zqT?eO$N-5vNVx==)e3%G7h5(T4-aJ`+-2w+vjyF#c_a+Qd$w6xJ=4oO} zHXKN^g`CugA~=wof+vU8IAcgu%SMod@ zNN-7JH0Qx-x++cykrn#~$mRW@6agS51n@ZHgnfuguIcKuGE8>562K$G!Z-wg)HhI$ zzSRK-QeGgRDvme8f%GttC)o82H6L9L^9zLfgFLr0xAh8(XnOqBRHsF=B@=6e9)a>( zio07!H#*yyPwe&XKPLw@&-gX=vE#$k6xzf_8+=mu(6pCT?2*0WRE*}Mm6%WBQmcHu zyJ+xGqjE*8iqwppJ4K#T;A8UI$vkWxJ1roscuZcOzKw7o)yg`Yn8@(QKP#P8UAPh%t~rbIJj;6CLd$@A%ctNB~kqu>76*`rWx|K#&du^EsmV z0vt$>cjdE<53KW4oTh7zIS1q%k96hZ#E8iV04XR$CZGEe97ykk@Y%w@0uH1OHa^R) zi*4m2pM}i5UvJ~1ZRtlAstPpq5}}e@^98w`T^8b5fE55K-YyGyEncKUkiU|DTU@bBq6m$+Q0h Di5%Y{ diff --git a/ElectronicObserver/Assets/Item/ActionReport.png b/ElectronicObserver/Assets/Item/ActionReport.png new file mode 100644 index 0000000000000000000000000000000000000000..99d41ccb7202304a71b1c64b2877bc71b2305399 GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPtkF21a$Wj9(MWB#uW=KSdbAE1aYF-JD%fR4Vl$uzQ znxasiS(2gP?&%wlqL<1J6tD7haSX9Iotz+%aiHT&p<&t&|24;K(-o^CFQ~@EI7xnc z6M6Q*BcZO9*$3s=+E~QfY^%c#x6b%*Q%OVPgaQz6NI##&F}qdLnOE5G951hLvq4ew z3FCyXuOcm;dK5G6WaCK{_la}Az^e1(%l`kLr#C+QTYXFIX(KyB!XL$>uT!2Bft=^* L>gTe~DWM4fV+UP> literal 0 HcmV?d00001 diff --git a/ElectronicObserver/Data/Constants.cs b/ElectronicObserver/Data/Constants.cs index 952b4adb0..3727f9ee9 100644 --- a/ElectronicObserver/Data/Constants.cs +++ b/ElectronicObserver/Data/Constants.cs @@ -8,1003 +8,1095 @@ namespace ElectronicObserver.Data { - public static class Constants - { - - #region 艦船・装備 - - /// - /// 艦船の速力を表す文字列を取得します。 - /// - public static string GetSpeed(int value) - { - switch (value) - { - case 0: - return "陸上"; - case 5: - return "低速"; - case 10: - return "高速"; - case 15: - return "高速+"; - case 20: - return "最速"; - default: - return "不明"; - } - } - - /// - /// 射程を表す文字列を取得します。 - /// - public static string GetRange(int value) - { - switch (value) - { - case 0: - return "無"; - case 1: - return "短"; - case 2: - return "中"; - case 3: - return "長"; - case 4: - return "超長"; - case 5: - return "超長+"; - default: - return "不明"; - } - } - - /// - /// 艦船のレアリティを表す文字列を取得します。 - /// - public static string GetShipRarity(int value) - { - switch (value) - { - case 0: - return "赤"; - case 1: - return "藍"; - case 2: - return "青"; - case 3: - return "水"; - case 4: - return "銀"; - case 5: - return "金"; - case 6: - return "虹"; - case 7: - return "輝虹"; - case 8: - return "桜虹"; - default: - return "不明"; - } - } - - /// - /// 装備のレアリティを表す文字列を取得します。 - /// - public static string GetEquipmentRarity(int value) - { - switch (value) - { - case 0: - return "コモン"; - case 1: - return "レア"; - case 2: - return "ホロ"; - case 3: - return "Sホロ"; - case 4: - return "SSホロ"; - case 5: - return "SSホロ'"; - case 6: - return "SSホロ+"; - default: - return "不明"; - } - } - - /// - /// 装備のレアリティの画像インデックスを取得します。 - /// - public static int GetEquipmentRarityID(int value) - { - switch (value) - { - case 0: - return 1; - case 1: - return 3; - case 2: - return 4; - case 3: - return 5; - case 4: - return 6; - case 5: - return 7; - case 6: - return 8; - default: - return 0; - } - } - - - /// - /// 艦船のボイス設定フラグを表す文字列を取得します。 - /// - public static string GetVoiceFlag(int value) - { - - switch (value) - { - case 0: - return "-"; - case 1: - return "時報"; - case 2: - return "放置"; - case 3: - return "時報+放置"; - case 4: - return "特殊放置"; - case 5: - return "時報+特殊放置"; - case 6: - return "放置+特殊放置"; - case 7: - return "時報+放置+特殊放置"; - default: - return "不明"; - } - } - - - /// - /// 艦船の損傷度合いを表す文字列を取得します。 - /// - /// 現在HP/最大HPで表される割合。 - /// 演習かどうか。 - /// 陸上基地かどうか。 - /// 退避中かどうか。 - /// - public static string GetDamageState(double hprate, bool isPractice = false, bool isLandBase = false, bool isEscaped = false) - { - - if (isEscaped) - return "退避"; - else if (hprate <= 0.0) - return isPractice ? "離脱" : (!isLandBase ? "撃沈" : "破壊"); - else if (hprate <= 0.25) - return !isLandBase ? "大破" : "損壊"; - else if (hprate <= 0.5) - return !isLandBase ? "中破" : "損害"; - else if (hprate <= 0.75) - return !isLandBase ? "小破" : "混乱"; - else if (hprate < 1.0) - return "健在"; - else - return "無傷"; - - } - - - /// - /// 基地航空隊の行動指示を表す文字列を取得します。 - /// - public static string GetBaseAirCorpsActionKind(int value) - { - switch (value) - { - case 0: - return "待機"; - case 1: - return "出撃"; - case 2: - return "防空"; - case 3: - return "退避"; - case 4: - return "休息"; - default: - return "不明"; - } - } - - - /// - /// 艦種略号を取得します。 - /// - public static string GetShipClassClassification(ShipTypes shiptype) - { - switch (shiptype) - { - case ShipTypes.Escort: - return "DE"; - case ShipTypes.Destroyer: - return "DD"; - case ShipTypes.LightCruiser: - return "CL"; - case ShipTypes.TorpedoCruiser: - return "CLT"; - case ShipTypes.HeavyCruiser: - return "CA"; - case ShipTypes.AviationCruiser: - return "CAV"; - case ShipTypes.LightAircraftCarrier: - return "CVL"; - case ShipTypes.Battlecruiser: - return "BC"; // ? FBB, CC? - case ShipTypes.Battleship: - return "BB"; - case ShipTypes.AviationBattleship: - return "BBV"; - case ShipTypes.AircraftCarrier: - return "CV"; - case ShipTypes.SuperDreadnoughts: - return "BB"; - case ShipTypes.Submarine: - return "SS"; - case ShipTypes.SubmarineAircraftCarrier: - return "SSV"; - case ShipTypes.Transport: - return "AP"; // ? AO? - case ShipTypes.SeaplaneTender: - return "AV"; - case ShipTypes.AmphibiousAssaultShip: - return "LHA"; - case ShipTypes.ArmoredAircraftCarrier: - return "CVB"; - case ShipTypes.RepairShip: - return "AR"; - case ShipTypes.SubmarineTender: - return "AS"; - case ShipTypes.TrainingCruiser: - return "CT"; - case ShipTypes.FleetOiler: - return "AO"; - default: - return "IX"; - } - } - - #endregion - - - #region 出撃 - - /// - /// マップ上のセルでのイベントを表す文字列を取得します。 - /// - public static string GetMapEventID(int value) - { - - switch (value) - { - - case 0: - return "初期位置"; - case 1: - return "なし"; - case 2: - return "資源"; - case 3: - return "渦潮"; - case 4: - return "通常戦闘"; - case 5: - return "ボス戦闘"; - case 6: - return "気のせいだった"; - case 7: - return "航空戦"; - case 8: - return "船団護衛成功"; - case 9: - return "揚陸地点"; - default: - return "不明"; - } - } - - /// - /// マップ上のセルでのイベント種別を表す文字列を取得します。 - /// - public static string GetMapEventKind(int value) - { - - switch (value) - { - case 0: - return "非戦闘"; - case 1: - return "昼夜戦"; - case 2: - return "夜戦"; - case 3: - return "夜昼戦"; // 対通常? - case 4: - return "航空戦"; - case 5: - return "敵連合"; - case 6: - return "空襲戦"; - case 7: - return "夜昼戦"; // 対連合 - default: - return "不明"; - } - } - - - /// - /// 海域難易度を表す文字列を取得します。 - /// - public static string GetDifficulty(int value) - { - - switch (value) - { - case -1: - return "なし"; - case 0: - return "未選択"; - case 1: - return "丙"; - case 2: - return "乙"; - case 3: - return "甲"; - default: - return "不明"; - } - } - - /// - /// 海域難易度を表す数値を取得します。 - /// - public static int GetDifficulty(string value) - { - - switch (value) - { - case "未選択": - return 0; - case "丙": - return 1; - case "乙": - return 2; - case "甲": - return 3; - default: - return -1; - } - - } - - /// - /// 空襲被害の状態を表す文字列を取得します。 - /// - public static string GetAirRaidDamage(int value) - { - switch (value) - { - case 1: - return "資源に損害"; - case 2: - return "資源・航空隊に損害"; - case 3: - return "航空隊に損害"; - case 4: - return "損害なし"; - default: - return "発生せず"; - } - } - - /// - /// 空襲被害の状態を表す文字列を取得します。(短縮版) - /// - public static string GetAirRaidDamageShort(int value) - { - switch (value) - { - case 1: - return "資源損害"; - case 2: - return "資源・航空"; - case 3: - return "航空隊損害"; - case 4: - return "損害なし"; - default: - return "-"; - } - } - - - #endregion - - - #region 戦闘 - - /// - /// 陣形を表す文字列を取得します。 - /// - public static string GetFormation(int id) - { - switch (id) - { - case 1: - return "単縦陣"; - case 2: - return "複縦陣"; - case 3: - return "輪形陣"; - case 4: - return "梯形陣"; - case 5: - return "単横陣"; - case 6: - return "警戒陣"; - case 11: - return "第一警戒航行序列"; - case 12: - return "第二警戒航行序列"; - case 13: - return "第三警戒航行序列"; - case 14: - return "第四警戒航行序列"; - default: - return "不明"; - } - } - - /// - /// 陣形を表す数値を取得します。 - /// - public static int GetFormation(string value) - { - switch (value) - { - case "単縦陣": - return 1; - case "複縦陣": - return 2; - case "輪形陣": - return 3; - case "梯形陣": - return 4; - case "単横陣": - return 5; - case "警戒陣": - return 6; - case "第一警戒航行序列": - return 11; - case "第二警戒航行序列": - return 12; - case "第三警戒航行序列": - return 13; - case "第四警戒航行序列": - return 14; - default: - return -1; - } - } - - /// - /// 陣形を表す文字列(短縮版)を取得します。 - /// - public static string GetFormationShort(int id) - { - switch (id) - { - case 1: - return "単縦陣"; - case 2: - return "複縦陣"; - case 3: - return "輪形陣"; - case 4: - return "梯形陣"; - case 5: - return "単横陣"; - case 6: - return "警戒陣"; - case 11: - return "第一警戒"; - case 12: - return "第二警戒"; - case 13: - return "第三警戒"; - case 14: - return "第四警戒"; - default: - return "不明"; - } - } - - /// - /// 交戦形態を表す文字列を取得します。 - /// - public static string GetEngagementForm(int id) - { - switch (id) - { - case 1: - return "同航戦"; - case 2: - return "反航戦"; - case 3: - return "T字有利"; - case 4: - return "T字不利"; - default: - return "不明"; - } - } - - /// - /// 索敵結果を表す文字列を取得します。 - /// - public static string GetSearchingResult(int id) - { - switch (id) - { - case 1: - return "成功"; - case 2: - return "成功(未帰還有)"; - case 3: - return "未帰還"; - case 4: - return "失敗"; - case 5: - return "成功(非索敵機)"; - case 6: - return "失敗(非索敵機)"; - default: - return "不明"; - } - } - - /// - /// 索敵結果を表す文字列(短縮版)を取得します。 - /// - public static string GetSearchingResultShort(int id) - { - switch (id) - { - case 1: - return "成功"; - case 2: - return "成功△"; - case 3: - return "未帰還"; - case 4: - return "失敗"; - case 5: - return "成功"; - case 6: - return "失敗"; - default: - return "不明"; - } - } - - /// - /// 制空戦の結果を表す文字列を取得します。 - /// - public static string GetAirSuperiority(int id) - { - switch (id) - { - case 0: - return "航空均衡"; - case 1: - return "制空権確保"; - case 2: - return "航空優勢"; - case 3: - return "航空劣勢"; - case 4: - return "制空権喪失"; - default: - return "不明"; - } - } - - - - /// - /// 昼戦攻撃種別を表す文字列を取得します。 - /// - public static string GetDayAttackKind(DayAttackKind id) - { - switch (id) - { - case DayAttackKind.NormalAttack: - return "通常攻撃"; - case DayAttackKind.Laser: - return "レーザー攻撃"; - case DayAttackKind.DoubleShelling: - return "連続射撃"; - case DayAttackKind.CutinMainSub: - return "カットイン(主砲/副砲)"; - case DayAttackKind.CutinMainRadar: - return "カットイン(主砲/電探)"; - case DayAttackKind.CutinMainAP: - return "カットイン(主砲/徹甲)"; - case DayAttackKind.CutinMainMain: - return "カットイン(主砲/主砲)"; - case DayAttackKind.CutinAirAttack: - return "空母カットイン"; - case DayAttackKind.Shelling: - return "砲撃"; - case DayAttackKind.AirAttack: - return "空撃"; - case DayAttackKind.DepthCharge: - return "爆雷攻撃"; - case DayAttackKind.Torpedo: - return "雷撃"; - case DayAttackKind.Rocket: - return "ロケット砲撃"; - case DayAttackKind.LandingDaihatsu: - return "揚陸攻撃(大発動艇)"; - case DayAttackKind.LandingTokuDaihatsu: - return "揚陸攻撃(特大発動艇)"; - case DayAttackKind.LandingDaihatsuTank: - return "揚陸攻撃(大発戦車)"; - case DayAttackKind.LandingAmphibious: - return "揚陸攻撃(内火艇)"; - case DayAttackKind.LandingTokuDaihatsuTank: - return "揚陸攻撃(特大発戦車)"; - default: - return "不明"; - } - } - - - /// - /// 夜戦攻撃種別を表す文字列を取得します。 - /// - public static string GetNightAttackKind(NightAttackKind id) - { - switch (id) - { - case NightAttackKind.NormalAttack: - return "通常攻撃"; - case NightAttackKind.DoubleShelling: - return "連続射撃"; - case NightAttackKind.CutinMainTorpedo: - return "カットイン(主砲/魚雷)"; - case NightAttackKind.CutinTorpedoTorpedo: - return "カットイン(魚雷x2)"; - case NightAttackKind.CutinMainSub: - return "カットイン(主砲x2/副砲)"; - case NightAttackKind.CutinMainMain: - return "カットイン(主砲x3)"; - case NightAttackKind.CutinAirAttack: - return "空母カットイン"; - case NightAttackKind.CutinTorpedoRadar: - return "駆逐カットイン(主砲/魚雷/電探)"; - case NightAttackKind.CutinTorpedoPicket: - return "駆逐カットイン(魚雷/見張員/電探)"; - case NightAttackKind.Shelling: - return "砲撃"; - case NightAttackKind.AirAttack: - return "空撃"; - case NightAttackKind.DepthCharge: - return "爆雷攻撃"; - case NightAttackKind.Torpedo: - return "雷撃"; - case NightAttackKind.Rocket: - return "ロケット砲撃"; - case NightAttackKind.LandingDaihatsu: - return "揚陸攻撃(大発動艇)"; - case NightAttackKind.LandingTokuDaihatsu: - return "揚陸攻撃(特大発動艇)"; - case NightAttackKind.LandingDaihatsuTank: - return "揚陸攻撃(大発戦車)"; - case NightAttackKind.LandingAmphibious: - return "揚陸攻撃(内火艇)"; - case NightAttackKind.LandingTokuDaihatsuTank: - return "揚陸攻撃(特大発戦車)"; - default: - return "不明"; - } - } - - - /// - /// 対空カットイン種別を表す文字列を取得します。 - /// - public static string GetAACutinKind(int id) - { - switch (id) - { - case 0: - return "なし"; - case 1: - return "高角砲x2/電探(秋月)"; - case 2: - return "高角砲/電探(秋月)"; - case 3: - return "高角砲x2(秋月)"; - case 4: - return "大口径主砲/三式弾/高射装置/電探"; - case 5: - return "高角砲+高射装置x2/電探"; - case 6: - return "大口径主砲/三式弾/高射装置"; - case 7: - return "高角砲/高射装置/電探"; - case 8: - return "高角砲+高射装置/電探"; - case 9: - return "高角砲/高射装置"; - case 10: - return "高角砲/集中機銃/電探(摩耶)"; - case 11: - return "高角砲/集中機銃(摩耶)"; - case 12: - return "集中機銃/機銃/電探"; - case 14: - return "高角砲/機銃/電探(五十鈴)"; - case 15: - return "高角砲/機銃(五十鈴)"; - case 16: - return "高角砲/機銃/電探(霞)"; - case 17: - return "高角砲/機銃(霞)"; - case 18: - return "集中機銃(皐月)"; - case 19: - return "高角砲(非高射装置)/集中機銃(鬼怒)"; - case 20: - return "集中機銃(鬼怒)"; - case 21: - return "高角砲/電探(由良)"; - case 22: - return "集中機銃(文月)"; - case 23: - return "機銃(非集中)(UIT-25)"; - default: - return "不明"; - } - } - - - /// - /// 勝利ランクを表すIDを取得します。 - /// - public static int GetWinRank(string rank) - { - switch (rank.ToUpper()) - { - case "E": - return 1; - case "D": - return 2; - case "C": - return 3; - case "B": - return 4; - case "A": - return 5; - case "S": - return 6; - case "SS": - return 7; - default: - return 0; - } - } - - /// - /// 勝利ランクを表す文字列を取得します。 - /// - public static string GetWinRank(int rank) - { - switch (rank) - { - case 1: - return "E"; - case 2: - return "D"; - case 3: - return "C"; - case 4: - return "B"; - case 5: - return "A"; - case 6: - return "S"; - case 7: - return "SS"; - default: - return "不明"; - } - } - - #endregion - - - #region その他 - - /// - /// 資源の名前を取得します。 - /// - /// 資源のID。 - /// 資源の名前。 - public static string GetMaterialName(int materialID) - { - - switch (materialID) - { - case 1: - return "燃料"; - case 2: - return "弾薬"; - case 3: - return "鋼材"; - case 4: - return "ボーキサイト"; - case 5: - return "高速建造材"; - case 6: - return "高速修復材"; - case 7: - return "開発資材"; - case 8: - return "改修資材"; - default: - return "不明"; - } - } - - - /// - /// 階級を表す文字列を取得します。 - /// - public static string GetAdmiralRank(int id) - { - switch (id) - { - case 1: - return "元帥"; - case 2: - return "大将"; - case 3: - return "中将"; - case 4: - return "少将"; - case 5: - return "大佐"; - case 6: - return "中佐"; - case 7: - return "新米中佐"; - case 8: - return "少佐"; - case 9: - return "中堅少佐"; - case 10: - return "新米少佐"; - default: - return "提督"; - } - } - - - /// - /// 任務の発生タイプを表す文字列を取得します。 - /// - public static string GetQuestType(int id) - { - switch (id) - { - case 1: //デイリー - return "日"; - case 2: //ウィークリー - return "週"; - case 3: //マンスリー - return "月"; - case 4: //単発 - return "単"; - case 5: //その他(輸送5/空母3) - return "他"; - default: - return "?"; - } - - } - - - /// - /// 任務のカテゴリを表す文字列を取得します。 - /// - public static string GetQuestCategory(int id) - { - switch (id) - { - case 1: - return "編成"; - case 2: - return "出撃"; - case 3: - return "演習"; - case 4: - return "遠征"; - case 5: - return "補給"; //入渠も含むが、文字数の関係 - case 6: - return "工廠"; - case 7: - return "改装"; - case 8: - return "出撃"; - case 9: - return "他"; - default: - return "不明"; - } - } - - - /// - /// 遠征の結果を表す文字列を取得します。 - /// - public static string GetExpeditionResult(int value) - { - switch (value) - { - case 0: - return "失敗"; - case 1: - return "成功"; - case 2: - return "大成功"; - default: - return "不明"; - } - } - - - /// - /// 連合艦隊の編成名を表す文字列を取得します。 - /// - public static string GetCombinedFleet(int value) - { - switch (value) - { - case 0: - return "通常艦隊"; - case 1: - return "機動部隊"; - case 2: - return "水上部隊"; - case 3: - return "輸送部隊"; - default: - return "不明"; - } - } - - #endregion - - } + public static class Constants + { + + #region 艦船・装備 + + /// + /// 艦船の速力を表す文字列を取得します。 + /// + public static string GetSpeed(int value) + { + switch (value) + { + case 0: + return "陸上"; + case 5: + return "低速"; + case 10: + return "高速"; + case 15: + return "高速+"; + case 20: + return "最速"; + default: + return "不明"; + } + } + + /// + /// 射程を表す文字列を取得します。 + /// + public static string GetRange(int value) + { + switch (value) + { + case 0: + return "無"; + case 1: + return "短"; + case 2: + return "中"; + case 3: + return "長"; + case 4: + return "超長"; + case 5: + return "超長+"; + default: + return "不明"; + } + } + + /// + /// 艦船のレアリティを表す文字列を取得します。 + /// + public static string GetShipRarity(int value) + { + switch (value) + { + case 0: + return "赤"; + case 1: + return "藍"; + case 2: + return "青"; + case 3: + return "水"; + case 4: + return "銀"; + case 5: + return "金"; + case 6: + return "虹"; + case 7: + return "輝虹"; + case 8: + return "桜虹"; + default: + return "不明"; + } + } + + /// + /// 装備のレアリティを表す文字列を取得します。 + /// + public static string GetEquipmentRarity(int value) + { + switch (value) + { + case 0: + return "コモン"; + case 1: + return "レア"; + case 2: + return "ホロ"; + case 3: + return "Sホロ"; + case 4: + return "SSホロ"; + case 5: + return "SSホロ'"; + case 6: + return "SSホロ+"; + default: + return "不明"; + } + } + + /// + /// 装備のレアリティの画像インデックスを取得します。 + /// + public static int GetEquipmentRarityID(int value) + { + switch (value) + { + case 0: + return 1; + case 1: + return 3; + case 2: + return 4; + case 3: + return 5; + case 4: + return 6; + case 5: + return 7; + case 6: + return 8; + default: + return 0; + } + } + + + /// + /// 艦船のボイス設定フラグを表す文字列を取得します。 + /// + public static string GetVoiceFlag(int value) + { + + switch (value) + { + case 0: + return "-"; + case 1: + return "時報"; + case 2: + return "放置"; + case 3: + return "時報+放置"; + case 4: + return "特殊放置"; + case 5: + return "時報+特殊放置"; + case 6: + return "放置+特殊放置"; + case 7: + return "時報+放置+特殊放置"; + default: + return "不明"; + } + } + + + /// + /// 艦船の損傷度合いを表す文字列を取得します。 + /// + /// 現在HP/最大HPで表される割合。 + /// 演習かどうか。 + /// 陸上基地かどうか。 + /// 退避中かどうか。 + /// + public static string GetDamageState(double hprate, bool isPractice = false, bool isLandBase = false, bool isEscaped = false) + { + + if (isEscaped) + return "退避"; + else if (hprate <= 0.0) + return isPractice ? "離脱" : (!isLandBase ? "撃沈" : "破壊"); + else if (hprate <= 0.25) + return !isLandBase ? "大破" : "損壊"; + else if (hprate <= 0.5) + return !isLandBase ? "中破" : "損害"; + else if (hprate <= 0.75) + return !isLandBase ? "小破" : "混乱"; + else if (hprate < 1.0) + return "健在"; + else + return "無傷"; + + } + + + /// + /// 基地航空隊の行動指示を表す文字列を取得します。 + /// + public static string GetBaseAirCorpsActionKind(int value) + { + switch (value) + { + case 0: + return "待機"; + case 1: + return "出撃"; + case 2: + return "防空"; + case 3: + return "退避"; + case 4: + return "休息"; + default: + return "不明"; + } + } + + + /// + /// 艦種略号を取得します。 + /// + public static string GetShipClassClassification(ShipTypes shiptype) + { + switch (shiptype) + { + case ShipTypes.Escort: + return "DE"; + case ShipTypes.Destroyer: + return "DD"; + case ShipTypes.LightCruiser: + return "CL"; + case ShipTypes.TorpedoCruiser: + return "CLT"; + case ShipTypes.HeavyCruiser: + return "CA"; + case ShipTypes.AviationCruiser: + return "CAV"; + case ShipTypes.LightAircraftCarrier: + return "CVL"; + case ShipTypes.Battlecruiser: + return "BC"; // ? FBB, CC? + case ShipTypes.Battleship: + return "BB"; + case ShipTypes.AviationBattleship: + return "BBV"; + case ShipTypes.AircraftCarrier: + return "CV"; + case ShipTypes.SuperDreadnoughts: + return "BB"; + case ShipTypes.Submarine: + return "SS"; + case ShipTypes.SubmarineAircraftCarrier: + return "SSV"; + case ShipTypes.Transport: + return "AP"; // ? AO? + case ShipTypes.SeaplaneTender: + return "AV"; + case ShipTypes.AmphibiousAssaultShip: + return "LHA"; + case ShipTypes.ArmoredAircraftCarrier: + return "CVB"; + case ShipTypes.RepairShip: + return "AR"; + case ShipTypes.SubmarineTender: + return "AS"; + case ShipTypes.TrainingCruiser: + return "CT"; + case ShipTypes.FleetOiler: + return "AO"; + default: + return "IX"; + } + } + + + /// + /// 艦型を表す文字列を取得します。 + /// + public static string GetShipClass(int id) + { + switch (id) + { + case 1: return "綾波型"; + case 2: return "伊勢型"; + case 3: return "加賀型"; + case 4: return "球磨型"; + case 5: return "暁型"; + case 6: return "金剛型"; + case 7: return "古鷹型"; + case 8: return "高雄型"; + case 9: return "最上型"; + case 10: return "初春型"; + case 11: return "祥鳳型"; + case 12: return "吹雪型"; + case 13: return "青葉型"; + case 14: return "赤城型"; + case 15: return "千歳型"; + case 16: return "川内型"; + case 17: return "蒼龍型"; + case 18: return "朝潮型"; + case 19: return "長門型"; + case 20: return "長良型"; + case 21: return "天龍型"; + case 22: return "島風型"; + case 23: return "白露型"; + case 24: return "飛鷹型"; + case 25: return "飛龍型"; + case 26: return "扶桑型"; + case 27: return "鳳翔型"; + case 28: return "睦月型"; + case 29: return "妙高型"; + case 30: return "陽炎型"; + case 31: return "利根型"; + case 32: return "龍驤型"; + case 33: return "翔鶴型"; + case 34: return "夕張型"; + case 35: return "海大VI型"; + case 36: return "巡潜乙型改二"; + case 37: return "大和型"; + case 38: return "夕雲型"; + case 39: return "巡潜乙型"; + case 40: return "巡潜3型"; + case 41: return "阿賀野型"; + case 42: return "「霧」"; + case 43: return "大鳳型"; + case 44: return "潜特型(伊400型潜水艦)"; + case 45: return "特種船丙型"; + case 46: return "三式潜航輸送艇"; + case 47: return "Bismarck級"; + case 48: return "Z1型"; + case 49: return "工作艦"; + case 50: return "大鯨型"; + case 51: return "龍鳳型"; + case 52: return "大淀型"; + case 53: return "雲龍型"; + case 54: return "秋月型"; + case 55: return "Admiral Hipper級"; + case 56: return "香取型"; + case 57: return "UボートIXC型/呂号潜水艦"; + case 58: return "V.Veneto級"; + case 59: return "秋津洲型"; + case 60: return "改風早型"; + case 61: return "Maestrale級"; + case 62: return "瑞穂型"; + case 63: return "Graf Zeppelin級"; + case 64: return "Zara級"; + case 65: return "Iowa級"; + case 66: return "神風型"; + case 67: return "Queen Elizabeth級"; + case 68: return "Aquila級"; + case 69: return "Lexington級"; + case 70: return "C.Teste級"; + case 71: return "巡潜甲型改二"; + case 72: return "神威型"; + case 73: return "Гангут級"; + case 74: return "占守型"; + case 75: return "春日丸級"; + case 76: return "大鷹型"; + case 77: return "択捉型"; + case 78: return "Ark Royal級"; + case 79: return "Richelieu級"; + case 80: return "Guglielmo Marconi級"; + default: return "不明"; + } + } + + #endregion + + + #region 出撃 + + /// + /// マップ上のセルでのイベントを表す文字列を取得します。 + /// + public static string GetMapEventID(int value) + { + + switch (value) + { + + case 0: + return "初期位置"; + case 1: + return "なし"; + case 2: + return "資源"; + case 3: + return "渦潮"; + case 4: + return "通常戦闘"; + case 5: + return "ボス戦闘"; + case 6: + return "気のせいだった"; + case 7: + return "航空戦"; + case 8: + return "船団護衛成功"; + case 9: + return "揚陸地点"; + default: + return "不明"; + } + } + + /// + /// マップ上のセルでのイベント種別を表す文字列を取得します。 + /// + public static string GetMapEventKind(int value) + { + + switch (value) + { + case 0: + return "非戦闘"; + case 1: + return "昼夜戦"; + case 2: + return "夜戦"; + case 3: + return "夜昼戦"; // 対通常? + case 4: + return "航空戦"; + case 5: + return "敵連合"; + case 6: + return "空襲戦"; + case 7: + return "夜昼戦"; // 対連合 + default: + return "不明"; + } + } + + + /// + /// 海域難易度を表す文字列を取得します。 + /// + public static string GetDifficulty(int value) + { + + switch (value) + { + case -1: + return "なし"; + case 0: + return "未選択"; + case 1: + return "丙"; + case 2: + return "乙"; + case 3: + return "甲"; + default: + return "不明"; + } + } + + /// + /// 海域難易度を表す数値を取得します。 + /// + public static int GetDifficulty(string value) + { + + switch (value) + { + case "未選択": + return 0; + case "丙": + return 1; + case "乙": + return 2; + case "甲": + return 3; + default: + return -1; + } + + } + + /// + /// 空襲被害の状態を表す文字列を取得します。 + /// + public static string GetAirRaidDamage(int value) + { + switch (value) + { + case 1: + return "資源に損害"; + case 2: + return "資源・航空隊に損害"; + case 3: + return "航空隊に損害"; + case 4: + return "損害なし"; + default: + return "発生せず"; + } + } + + /// + /// 空襲被害の状態を表す文字列を取得します。(短縮版) + /// + public static string GetAirRaidDamageShort(int value) + { + switch (value) + { + case 1: + return "資源損害"; + case 2: + return "資源・航空"; + case 3: + return "航空隊損害"; + case 4: + return "損害なし"; + default: + return "-"; + } + } + + + #endregion + + + #region 戦闘 + + /// + /// 陣形を表す文字列を取得します。 + /// + public static string GetFormation(int id) + { + switch (id) + { + case 1: + return "単縦陣"; + case 2: + return "複縦陣"; + case 3: + return "輪形陣"; + case 4: + return "梯形陣"; + case 5: + return "単横陣"; + case 6: + return "警戒陣"; + case 11: + return "第一警戒航行序列"; + case 12: + return "第二警戒航行序列"; + case 13: + return "第三警戒航行序列"; + case 14: + return "第四警戒航行序列"; + default: + return "不明"; + } + } + + /// + /// 陣形を表す数値を取得します。 + /// + public static int GetFormation(string value) + { + switch (value) + { + case "単縦陣": + return 1; + case "複縦陣": + return 2; + case "輪形陣": + return 3; + case "梯形陣": + return 4; + case "単横陣": + return 5; + case "警戒陣": + return 6; + case "第一警戒航行序列": + return 11; + case "第二警戒航行序列": + return 12; + case "第三警戒航行序列": + return 13; + case "第四警戒航行序列": + return 14; + default: + return -1; + } + } + + /// + /// 陣形を表す文字列(短縮版)を取得します。 + /// + public static string GetFormationShort(int id) + { + switch (id) + { + case 1: + return "単縦陣"; + case 2: + return "複縦陣"; + case 3: + return "輪形陣"; + case 4: + return "梯形陣"; + case 5: + return "単横陣"; + case 6: + return "警戒陣"; + case 11: + return "第一警戒"; + case 12: + return "第二警戒"; + case 13: + return "第三警戒"; + case 14: + return "第四警戒"; + default: + return "不明"; + } + } + + /// + /// 交戦形態を表す文字列を取得します。 + /// + public static string GetEngagementForm(int id) + { + switch (id) + { + case 1: + return "同航戦"; + case 2: + return "反航戦"; + case 3: + return "T字有利"; + case 4: + return "T字不利"; + default: + return "不明"; + } + } + + /// + /// 索敵結果を表す文字列を取得します。 + /// + public static string GetSearchingResult(int id) + { + switch (id) + { + case 1: + return "成功"; + case 2: + return "成功(未帰還有)"; + case 3: + return "未帰還"; + case 4: + return "失敗"; + case 5: + return "成功(非索敵機)"; + case 6: + return "失敗(非索敵機)"; + default: + return "不明"; + } + } + + /// + /// 索敵結果を表す文字列(短縮版)を取得します。 + /// + public static string GetSearchingResultShort(int id) + { + switch (id) + { + case 1: + return "成功"; + case 2: + return "成功△"; + case 3: + return "未帰還"; + case 4: + return "失敗"; + case 5: + return "成功"; + case 6: + return "失敗"; + default: + return "不明"; + } + } + + /// + /// 制空戦の結果を表す文字列を取得します。 + /// + public static string GetAirSuperiority(int id) + { + switch (id) + { + case 0: + return "航空均衡"; + case 1: + return "制空権確保"; + case 2: + return "航空優勢"; + case 3: + return "航空劣勢"; + case 4: + return "制空権喪失"; + default: + return "不明"; + } + } + + + + /// + /// 昼戦攻撃種別を表す文字列を取得します。 + /// + public static string GetDayAttackKind(DayAttackKind id) + { + switch (id) + { + case DayAttackKind.NormalAttack: + return "通常攻撃"; + case DayAttackKind.Laser: + return "レーザー攻撃"; + case DayAttackKind.DoubleShelling: + return "連続射撃"; + case DayAttackKind.CutinMainSub: + return "カットイン(主砲/副砲)"; + case DayAttackKind.CutinMainRadar: + return "カットイン(主砲/電探)"; + case DayAttackKind.CutinMainAP: + return "カットイン(主砲/徹甲)"; + case DayAttackKind.CutinMainMain: + return "カットイン(主砲/主砲)"; + case DayAttackKind.CutinAirAttack: + return "空母カットイン"; + case DayAttackKind.Shelling: + return "砲撃"; + case DayAttackKind.AirAttack: + return "空撃"; + case DayAttackKind.DepthCharge: + return "爆雷攻撃"; + case DayAttackKind.Torpedo: + return "雷撃"; + case DayAttackKind.Rocket: + return "ロケット砲撃"; + case DayAttackKind.LandingDaihatsu: + return "揚陸攻撃(大発動艇)"; + case DayAttackKind.LandingTokuDaihatsu: + return "揚陸攻撃(特大発動艇)"; + case DayAttackKind.LandingDaihatsuTank: + return "揚陸攻撃(大発戦車)"; + case DayAttackKind.LandingAmphibious: + return "揚陸攻撃(内火艇)"; + case DayAttackKind.LandingTokuDaihatsuTank: + return "揚陸攻撃(特大発戦車)"; + default: + return "不明"; + } + } + + + /// + /// 夜戦攻撃種別を表す文字列を取得します。 + /// + public static string GetNightAttackKind(NightAttackKind id) + { + switch (id) + { + case NightAttackKind.NormalAttack: + return "通常攻撃"; + case NightAttackKind.DoubleShelling: + return "連続射撃"; + case NightAttackKind.CutinMainTorpedo: + return "カットイン(主砲/魚雷)"; + case NightAttackKind.CutinTorpedoTorpedo: + return "カットイン(魚雷x2)"; + case NightAttackKind.CutinMainSub: + return "カットイン(主砲x2/副砲)"; + case NightAttackKind.CutinMainMain: + return "カットイン(主砲x3)"; + case NightAttackKind.CutinAirAttack: + return "空母カットイン"; + case NightAttackKind.CutinTorpedoRadar: + return "駆逐カットイン(主砲/魚雷/電探)"; + case NightAttackKind.CutinTorpedoPicket: + return "駆逐カットイン(魚雷/見張員/電探)"; + case NightAttackKind.Shelling: + return "砲撃"; + case NightAttackKind.AirAttack: + return "空撃"; + case NightAttackKind.DepthCharge: + return "爆雷攻撃"; + case NightAttackKind.Torpedo: + return "雷撃"; + case NightAttackKind.Rocket: + return "ロケット砲撃"; + case NightAttackKind.LandingDaihatsu: + return "揚陸攻撃(大発動艇)"; + case NightAttackKind.LandingTokuDaihatsu: + return "揚陸攻撃(特大発動艇)"; + case NightAttackKind.LandingDaihatsuTank: + return "揚陸攻撃(大発戦車)"; + case NightAttackKind.LandingAmphibious: + return "揚陸攻撃(内火艇)"; + case NightAttackKind.LandingTokuDaihatsuTank: + return "揚陸攻撃(特大発戦車)"; + default: + return "不明"; + } + } + + + /// + /// 対空カットイン種別を表す文字列を取得します。 + /// + public static string GetAACutinKind(int id) + { + switch (id) + { + case 0: + return "なし"; + case 1: + return "高角砲x2/電探(秋月)"; + case 2: + return "高角砲/電探(秋月)"; + case 3: + return "高角砲x2(秋月)"; + case 4: + return "大口径主砲/三式弾/高射装置/電探"; + case 5: + return "高角砲+高射装置x2/電探"; + case 6: + return "大口径主砲/三式弾/高射装置"; + case 7: + return "高角砲/高射装置/電探"; + case 8: + return "高角砲+高射装置/電探"; + case 9: + return "高角砲/高射装置"; + case 10: + return "高角砲/集中機銃/電探(摩耶)"; + case 11: + return "高角砲/集中機銃(摩耶)"; + case 12: + return "集中機銃/機銃/電探"; + case 14: + return "高角砲/機銃/電探(五十鈴)"; + case 15: + return "高角砲/機銃(五十鈴)"; + case 16: + return "高角砲/機銃/電探(霞)"; + case 17: + return "高角砲/機銃(霞)"; + case 18: + return "集中機銃(皐月)"; + case 19: + return "高角砲(非高射装置)/集中機銃(鬼怒)"; + case 20: + return "集中機銃(鬼怒)"; + case 21: + return "高角砲/電探(由良)"; + case 22: + return "集中機銃(文月)"; + case 23: + return "機銃(非集中)(UIT-25)"; + default: + return "不明"; + } + } + + + /// + /// 勝利ランクを表すIDを取得します。 + /// + public static int GetWinRank(string rank) + { + switch (rank.ToUpper()) + { + case "E": + return 1; + case "D": + return 2; + case "C": + return 3; + case "B": + return 4; + case "A": + return 5; + case "S": + return 6; + case "SS": + return 7; + default: + return 0; + } + } + + /// + /// 勝利ランクを表す文字列を取得します。 + /// + public static string GetWinRank(int rank) + { + switch (rank) + { + case 1: + return "E"; + case 2: + return "D"; + case 3: + return "C"; + case 4: + return "B"; + case 5: + return "A"; + case 6: + return "S"; + case 7: + return "SS"; + default: + return "不明"; + } + } + + #endregion + + + #region その他 + + /// + /// 資源の名前を取得します。 + /// + /// 資源のID。 + /// 資源の名前。 + public static string GetMaterialName(int materialID) + { + + switch (materialID) + { + case 1: + return "燃料"; + case 2: + return "弾薬"; + case 3: + return "鋼材"; + case 4: + return "ボーキサイト"; + case 5: + return "高速建造材"; + case 6: + return "高速修復材"; + case 7: + return "開発資材"; + case 8: + return "改修資材"; + default: + return "不明"; + } + } + + + /// + /// 階級を表す文字列を取得します。 + /// + public static string GetAdmiralRank(int id) + { + switch (id) + { + case 1: + return "元帥"; + case 2: + return "大将"; + case 3: + return "中将"; + case 4: + return "少将"; + case 5: + return "大佐"; + case 6: + return "中佐"; + case 7: + return "新米中佐"; + case 8: + return "少佐"; + case 9: + return "中堅少佐"; + case 10: + return "新米少佐"; + default: + return "提督"; + } + } + + + /// + /// 任務の発生タイプを表す文字列を取得します。 + /// + public static string GetQuestType(int id) + { + switch (id) + { + case 1: //デイリー + return "日"; + case 2: //ウィークリー + return "週"; + case 3: //マンスリー + return "月"; + case 4: //単発 + return "単"; + case 5: //その他(輸送5/空母3) + return "他"; + default: + return "?"; + } + + } + + + /// + /// 任務のカテゴリを表す文字列を取得します。 + /// + public static string GetQuestCategory(int id) + { + switch (id) + { + case 1: + return "編成"; + case 2: + return "出撃"; + case 3: + return "演習"; + case 4: + return "遠征"; + case 5: + return "補給"; //入渠も含むが、文字数の関係 + case 6: + return "工廠"; + case 7: + return "改装"; + case 8: + return "出撃"; + case 9: + return "他"; + default: + return "不明"; + } + } + + + /// + /// 遠征の結果を表す文字列を取得します。 + /// + public static string GetExpeditionResult(int value) + { + switch (value) + { + case 0: + return "失敗"; + case 1: + return "成功"; + case 2: + return "大成功"; + default: + return "不明"; + } + } + + + /// + /// 連合艦隊の編成名を表す文字列を取得します。 + /// + public static string GetCombinedFleet(int value) + { + switch (value) + { + case 0: + return "通常艦隊"; + case 1: + return "機動部隊"; + case 2: + return "水上部隊"; + case 3: + return "輸送部隊"; + default: + return "不明"; + } + } + + #endregion + + } } diff --git a/ElectronicObserver/Data/ShipData.cs b/ElectronicObserver/Data/ShipData.cs index 9127e3bdb..eac6107f5 100644 --- a/ElectronicObserver/Data/ShipData.cs +++ b/ElectronicObserver/Data/ShipData.cs @@ -12,1512 +12,1539 @@ namespace ElectronicObserver.Data { - /// - /// 個別の艦娘データを保持します。 - /// - public class ShipData : APIWrapper, IIdentifiable - { + /// + /// 個別の艦娘データを保持します。 + /// + public class ShipData : APIWrapper, IIdentifiable + { - /// - /// 艦娘を一意に識別するID - /// - public int MasterID => (int)RawData.api_id; + /// + /// 艦娘を一意に識別するID + /// + public int MasterID => (int)RawData.api_id; - /// - /// 並べ替えの順番 - /// - public int SortID => (int)RawData.api_sortno; + /// + /// 並べ替えの順番 + /// + public int SortID => (int)RawData.api_sortno; - /// - /// 艦船ID - /// - public int ShipID => (int)RawData.api_ship_id; + /// + /// 艦船ID + /// + public int ShipID => (int)RawData.api_ship_id; - /// - /// レベル - /// - public int Level => (int)RawData.api_lv; + /// + /// レベル + /// + public int Level => (int)RawData.api_lv; - /// - /// 累積経験値 - /// - public int ExpTotal => (int)RawData.api_exp[0]; + /// + /// 累積経験値 + /// + public int ExpTotal => (int)RawData.api_exp[0]; - /// - /// 次のレベルに達するために必要な経験値 - /// - public int ExpNext => (int)RawData.api_exp[1]; + /// + /// 次のレベルに達するために必要な経験値 + /// + public int ExpNext => (int)RawData.api_exp[1]; - /// - /// 耐久現在値 - /// - public int HPCurrent { get; internal set; } + /// + /// 耐久現在値 + /// + public int HPCurrent { get; internal set; } - /// - /// 耐久最大値 - /// - public int HPMax => (int)RawData.api_maxhp; + /// + /// 耐久最大値 + /// + public int HPMax => (int)RawData.api_maxhp; - /// - /// 速力 - /// - public int Speed => RawData.api_soku() ? (int)RawData.api_soku : MasterShip.Speed; + /// + /// 速力 + /// + public int Speed => RawData.api_soku() ? (int)RawData.api_soku : MasterShip.Speed; - /// - /// 射程 - /// - public int Range => (int)RawData.api_leng; + /// + /// 射程 + /// + public int Range => (int)RawData.api_leng; - /// - /// 装備スロット(ID) - /// - public ReadOnlyCollection Slot { get; private set; } + /// + /// 装備スロット(ID) + /// + public ReadOnlyCollection Slot { get; private set; } - /// - /// 装備スロット(マスターID) - /// - public ReadOnlyCollection SlotMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); + /// + /// 装備スロット(マスターID) + /// + public ReadOnlyCollection SlotMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); - /// - /// 装備スロット(装備データ) - /// - public ReadOnlyCollection SlotInstance => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); + /// + /// 装備スロット(装備データ) + /// + public ReadOnlyCollection SlotInstance => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); - /// - /// 装備スロット(装備マスターデータ) - /// - public ReadOnlyCollection SlotInstanceMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); + /// + /// 装備スロット(装備マスターデータ) + /// + public ReadOnlyCollection SlotInstanceMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); - /// - /// 補強装備スロット(ID) - /// 0=未開放, -1=装備なし - /// - public int ExpansionSlot { get; private set; } + /// + /// 補強装備スロット(ID) + /// 0=未開放, -1=装備なし + /// + public int ExpansionSlot { get; private set; } - /// - /// 補強装備スロット(マスターID) - /// - public int ExpansionSlotMaster => ExpansionSlot == 0 ? 0 : (KCDatabase.Instance.Equipments[ExpansionSlot]?.EquipmentID ?? -1); + /// + /// 補強装備スロット(マスターID) + /// + public int ExpansionSlotMaster => ExpansionSlot == 0 ? 0 : (KCDatabase.Instance.Equipments[ExpansionSlot]?.EquipmentID ?? -1); - /// - /// 補強装備スロット(装備データ) - /// - public EquipmentData ExpansionSlotInstance => KCDatabase.Instance.Equipments[ExpansionSlot]; + /// + /// 補強装備スロット(装備データ) + /// + public EquipmentData ExpansionSlotInstance => KCDatabase.Instance.Equipments[ExpansionSlot]; - /// - /// 補強装備スロット(装備マスターデータ) - /// - public EquipmentDataMaster ExpansionSlotInstanceMaster => KCDatabase.Instance.Equipments[ExpansionSlot]?.MasterEquipment; + /// + /// 補強装備スロット(装備マスターデータ) + /// + public EquipmentDataMaster ExpansionSlotInstanceMaster => KCDatabase.Instance.Equipments[ExpansionSlot]?.MasterEquipment; - /// - /// 全てのスロット(ID) - /// - public ReadOnlyCollection AllSlot => Array.AsReadOnly(Slot.Concat(new[] { ExpansionSlot }).ToArray()); + /// + /// 全てのスロット(ID) + /// + public ReadOnlyCollection AllSlot => Array.AsReadOnly(Slot.Concat(new[] { ExpansionSlot }).ToArray()); - /// - /// 全てのスロット(マスターID) - /// - public ReadOnlyCollection AllSlotMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); + /// + /// 全てのスロット(マスターID) + /// + public ReadOnlyCollection AllSlotMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); - /// - /// 全てのスロット(装備データ) - /// - public ReadOnlyCollection AllSlotInstance => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); + /// + /// 全てのスロット(装備データ) + /// + public ReadOnlyCollection AllSlotInstance => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); - /// - /// 全てのスロット(装備マスターデータ) - /// - public ReadOnlyCollection AllSlotInstanceMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); + /// + /// 全てのスロット(装備マスターデータ) + /// + public ReadOnlyCollection AllSlotInstanceMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); - private int[] _aircraft; - /// - /// 各スロットの航空機搭載量 - /// - public ReadOnlyCollection Aircraft => Array.AsReadOnly(_aircraft); + private int[] _aircraft; + /// + /// 各スロットの航空機搭載量 + /// + public ReadOnlyCollection Aircraft => Array.AsReadOnly(_aircraft); - /// - /// 現在の航空機搭載量 - /// - public int AircraftTotal => _aircraft.Sum(a => Math.Max(a, 0)); + /// + /// 現在の航空機搭載量 + /// + public int AircraftTotal => _aircraft.Sum(a => Math.Max(a, 0)); - /// - /// 搭載燃料 - /// - public int Fuel { get; internal set; } + /// + /// 搭載燃料 + /// + public int Fuel { get; internal set; } - /// - /// 搭載弾薬 - /// - public int Ammo { get; internal set; } + /// + /// 搭載弾薬 + /// + public int Ammo { get; internal set; } - /// - /// スロットのサイズ - /// - public int SlotSize => !RawData.api_slotnum() ? 0 : (int)RawData.api_slotnum; + /// + /// スロットのサイズ + /// + public int SlotSize => !RawData.api_slotnum() ? 0 : (int)RawData.api_slotnum; - /// - /// 入渠にかかる時間(ミリ秒) - /// - public int RepairTime => (int)RawData.api_ndock_time; + /// + /// 入渠にかかる時間(ミリ秒) + /// + public int RepairTime => (int)RawData.api_ndock_time; - /// - /// 入渠にかかる鋼材 - /// - public int RepairSteel => (int)RawData.api_ndock_item[1]; + /// + /// 入渠にかかる鋼材 + /// + public int RepairSteel => (int)RawData.api_ndock_item[1]; - /// - /// 入渠にかかる燃料 - /// - public int RepairFuel => (int)RawData.api_ndock_item[0]; + /// + /// 入渠にかかる燃料 + /// + public int RepairFuel => (int)RawData.api_ndock_item[0]; - /// - /// コンディション - /// - public int Condition { get; internal set; } + /// + /// コンディション + /// + public int Condition { get; internal set; } - #region Parameters + #region Parameters - /******************************************************** + /******************************************************** * 強化値:近代化改修・レベルアップによって上昇した数値 * 総合値:装備込みでのパラメータ * 基本値:装備なしでのパラメータ(初期値+強化値) ********************************************************/ - private int[] _modernized; - /// - /// 火力強化値 - /// - public int FirepowerModernized => _modernized.Length >= 5 ? _modernized[0] : 0; - - /// - /// 雷装強化値 - /// - public int TorpedoModernized => _modernized.Length >= 5 ? _modernized[1] : 0; - - /// - /// 対空強化値 - /// - public int AAModernized => _modernized.Length >= 5 ? _modernized[2] : 0; - - /// - /// 装甲強化値 - /// - public int ArmorModernized => _modernized.Length >= 5 ? _modernized[3] : 0; - - /// - /// 運強化値 - /// - public int LuckModernized => _modernized.Length >= 5 ? _modernized[4] : 0; - - /// - /// 耐久強化値 - /// - public int HPMaxModernized => _modernized.Length >= 7 ? _modernized[5] : 0; - - /// - /// 対潜強化値 - /// - public int ASWModernized => _modernized.Length >= 7 ? _modernized[6] : 0; - - - /// - /// 火力改修残り - /// - public int FirepowerRemain => (MasterShip.FirepowerMax - MasterShip.FirepowerMin) - FirepowerModernized; - - /// - /// 雷装改修残り - /// - public int TorpedoRemain => (MasterShip.TorpedoMax - MasterShip.TorpedoMin) - TorpedoModernized; - - /// - /// 対空改修残り - /// - public int AARemain => (MasterShip.AAMax - MasterShip.AAMin) - AAModernized; - - /// - /// 装甲改修残り - /// - public int ArmorRemain => (MasterShip.ArmorMax - MasterShip.ArmorMin) - ArmorModernized; - - /// - /// 運改修残り - /// - public int LuckRemain => (MasterShip.LuckMax - MasterShip.LuckMin) - LuckModernized; - - /// - /// 耐久改修残り - /// - public int HPMaxRemain => (IsMarried ? MasterShip.HPMaxMarriedModernizable : MasterShip.HPMaxModernizable) - HPMaxModernized; - - /// - /// 対潜改修残り - /// - public int ASWRemain => ASWMax <= 0 ? 0 : MasterShip.ASWModernizable - ASWModernized; - - - /// - /// 火力総合値 - /// - public int FirepowerTotal => (int)RawData.api_karyoku[0]; - - /// - /// 雷装総合値 - /// - public int TorpedoTotal => (int)RawData.api_raisou[0]; - - /// - /// 対空総合値 - /// - public int AATotal => (int)RawData.api_taiku[0]; - - /// - /// 装甲総合値 - /// - public int ArmorTotal => (int)RawData.api_soukou[0]; - - /// - /// 回避総合値 - /// - public int EvasionTotal => (int)RawData.api_kaihi[0]; - - /// - /// 対潜総合値 - /// - public int ASWTotal => (int)RawData.api_taisen[0]; - - /// - /// 索敵総合値 - /// - public int LOSTotal => (int)RawData.api_sakuteki[0]; - - /// - /// 運総合値 - /// - public int LuckTotal => (int)RawData.api_lucky[0]; - - /// - /// 爆装総合値 - /// - public int BomberTotal => AllSlotInstanceMaster.Sum(s => s == null ? 0 : Math.Max(s.Bomber, 0)); - - - /// - /// 火力基本値 - /// - public int FirepowerBase => MasterShip.FirepowerMin + FirepowerModernized; - - - /// - /// 雷装基本値 - /// - public int TorpedoBase => MasterShip.TorpedoMin + TorpedoModernized; - - - /// - /// 対空基本値 - /// - public int AABase => MasterShip.AAMin + AAModernized; - - - /// - /// 装甲基本値 - /// - public int ArmorBase => MasterShip.ArmorMin + ArmorModernized; - - - /// - /// 回避基本値 - /// - public int EvasionBase - { - get - { - int param = EvasionTotal; - var eqs = AllSlotInstance.Where(eq => eq != null); - foreach (var eq in eqs) - { - param -= eq.MasterEquipment.Evasion; - } - - // 北方迷彩(+北方装備) による特殊補正(重複しない) - if (eqs.Any(eq => eq.EquipmentID == 268)) - { - switch (ShipID) - { - case 146: // 木曾改二 - case 216: // 多摩改 - case 217: // 木曾改 - case 547: // 多摩改二 - param -= 7; - break; - } - } - return param; - } - } - - /// - /// 対潜基本値 - /// - public int ASWBase - { - get - { - int param = ASWTotal; - foreach (var eq in AllSlotInstance.Where(eq => eq != null)) - { - param -= eq.MasterEquipment.ASW; - } - return param; - } - } - - /// - /// 索敵基本値 - /// - public int LOSBase - { - get - { - int param = LOSTotal; - foreach (var eq in AllSlotInstance.Where(eq => eq != null)) - { - param -= eq.MasterEquipment.LOS; - } - return param; - } - } - - /// - /// 運基本値 - /// - public int LuckBase => MasterShip.LuckMin + LuckModernized; - - - - /// - /// 回避最大値 - /// - public int EvasionMax => (int)RawData.api_kaihi[1]; - - /// - /// 対潜最大値 - /// - public int ASWMax => (int)RawData.api_taisen[1]; - - /// - /// 索敵最大値 - /// - public int LOSMax => (int)RawData.api_sakuteki[1]; - - #endregion - - - /// - /// 保護ロックの有無 - /// - public bool IsLocked => (int)RawData.api_locked != 0; - - /// - /// 装備による保護ロックの有無 - /// - public bool IsLockedByEquipment => (int)RawData.api_locked_equip != 0; - - - /// - /// 出撃海域 - /// - public int SallyArea => RawData.api_sally_area() ? (int)RawData.api_sally_area : -1; - - - - /// - /// 艦船のマスターデータへの参照 - /// - public ShipDataMaster MasterShip => KCDatabase.Instance.MasterShips[ShipID]; - - - /// - /// 入渠中のドックID 非入渠時は-1 - /// - public int RepairingDockID => KCDatabase.Instance.Docks.Values.FirstOrDefault(dock => dock.ShipID == MasterID)?.DockID ?? -1; - - - /// - /// 所属艦隊 -1=なし - /// - public int Fleet => KCDatabase.Instance.Fleet.Fleets.Values.FirstOrDefault(f => f.Members.Contains(MasterID))?.FleetID ?? -1; - - - - /// - /// 所属艦隊及びその位置 - /// ex. 1-3 (位置も1から始まる) - /// 所属していなければ 空文字列 - /// - public string FleetWithIndex - { - get - { - FleetManager fm = KCDatabase.Instance.Fleet; - foreach (var f in fm.Fleets.Values) - { - int index = f.Members.IndexOf(MasterID); - if (index != -1) - { - return $"{f.FleetID}-{index + 1}"; - } - } - return ""; - } + private int[] _modernized; + /// + /// 火力強化値 + /// + public int FirepowerModernized => _modernized.Length >= 5 ? _modernized[0] : 0; + + /// + /// 雷装強化値 + /// + public int TorpedoModernized => _modernized.Length >= 5 ? _modernized[1] : 0; + + /// + /// 対空強化値 + /// + public int AAModernized => _modernized.Length >= 5 ? _modernized[2] : 0; + + /// + /// 装甲強化値 + /// + public int ArmorModernized => _modernized.Length >= 5 ? _modernized[3] : 0; + + /// + /// 運強化値 + /// + public int LuckModernized => _modernized.Length >= 5 ? _modernized[4] : 0; + + /// + /// 耐久強化値 + /// + public int HPMaxModernized => _modernized.Length >= 7 ? _modernized[5] : 0; + + /// + /// 対潜強化値 + /// + public int ASWModernized => _modernized.Length >= 7 ? _modernized[6] : 0; + + + /// + /// 火力改修残り + /// + public int FirepowerRemain => (MasterShip.FirepowerMax - MasterShip.FirepowerMin) - FirepowerModernized; + + /// + /// 雷装改修残り + /// + public int TorpedoRemain => (MasterShip.TorpedoMax - MasterShip.TorpedoMin) - TorpedoModernized; + + /// + /// 対空改修残り + /// + public int AARemain => (MasterShip.AAMax - MasterShip.AAMin) - AAModernized; + + /// + /// 装甲改修残り + /// + public int ArmorRemain => (MasterShip.ArmorMax - MasterShip.ArmorMin) - ArmorModernized; + + /// + /// 運改修残り + /// + public int LuckRemain => (MasterShip.LuckMax - MasterShip.LuckMin) - LuckModernized; + + /// + /// 耐久改修残り + /// + public int HPMaxRemain => (IsMarried ? MasterShip.HPMaxMarriedModernizable : MasterShip.HPMaxModernizable) - HPMaxModernized; + + /// + /// 対潜改修残り + /// + public int ASWRemain => ASWMax <= 0 ? 0 : MasterShip.ASWModernizable - ASWModernized; + + + /// + /// 火力総合値 + /// + public int FirepowerTotal => (int)RawData.api_karyoku[0]; + + /// + /// 雷装総合値 + /// + public int TorpedoTotal => (int)RawData.api_raisou[0]; + + /// + /// 対空総合値 + /// + public int AATotal => (int)RawData.api_taiku[0]; + + /// + /// 装甲総合値 + /// + public int ArmorTotal => (int)RawData.api_soukou[0]; + + /// + /// 回避総合値 + /// + public int EvasionTotal => (int)RawData.api_kaihi[0]; + + /// + /// 対潜総合値 + /// + public int ASWTotal => (int)RawData.api_taisen[0]; + + /// + /// 索敵総合値 + /// + public int LOSTotal => (int)RawData.api_sakuteki[0]; + + /// + /// 運総合値 + /// + public int LuckTotal => (int)RawData.api_lucky[0]; + + /// + /// 爆装総合値 + /// + public int BomberTotal => AllSlotInstanceMaster.Sum(s => s == null ? 0 : Math.Max(s.Bomber, 0)); + + + /// + /// 火力基本値 + /// + public int FirepowerBase => MasterShip.FirepowerMin + FirepowerModernized; + + + /// + /// 雷装基本値 + /// + public int TorpedoBase => MasterShip.TorpedoMin + TorpedoModernized; + + + /// + /// 対空基本値 + /// + public int AABase => MasterShip.AAMin + AAModernized; + + + /// + /// 装甲基本値 + /// + public int ArmorBase => MasterShip.ArmorMin + ArmorModernized; + + + /// + /// 回避基本値 + /// + public int EvasionBase + { + get + { + int param = EvasionTotal; + bool hasNaganamiGun = false; + + var eqs = AllSlotInstance.Where(eq => eq != null); + foreach (var eq in eqs) + { + param -= eq.MasterEquipment.Evasion; + + if (eq.EquipmentID == 267) // 12.7cm連装砲D型改二 + { + hasNaganamiGun = true; + + if (ShipID == 543 || // 長波改二 + MasterShip.ShipClass == 22 || // 島風型 + MasterShip.ShipClass == 38 || // 夕雲型 + MasterShip.ShipClass == 30) // 陽炎型 + { + param -= 1; + } + } + } + + // 北方迷彩(+北方装備) による特殊補正(重複しない) + if (eqs.Any(eq => eq.EquipmentID == 268)) + { + switch (ShipID) + { + case 146: // 木曾改二 + case 216: // 多摩改 + case 217: // 木曾改 + case 547: // 多摩改二 + param -= 7; + break; + } + } + + // 12.7cm連装砲D型改二 + 水上電探 による特殊補正 + if (hasNaganamiGun && + (ShipID == 229 || ShipID == 543) && // 島風改, 長波改二 + eqs.Any(eq => eq.MasterEquipment.IsSurfaceRadar)) + { + param -= 2; + } + + return param; + } + } + + /// + /// 対潜基本値 + /// + public int ASWBase + { + get + { + int param = ASWTotal; + foreach (var eq in AllSlotInstance.Where(eq => eq != null)) + { + param -= eq.MasterEquipment.ASW; + } + return param; + } + } + + /// + /// 索敵基本値 + /// + public int LOSBase + { + get + { + int param = LOSTotal; + foreach (var eq in AllSlotInstance.Where(eq => eq != null)) + { + param -= eq.MasterEquipment.LOS; + } + return param; + } + } + + /// + /// 運基本値 + /// + public int LuckBase => MasterShip.LuckMin + LuckModernized; + + + + /// + /// 回避最大値 + /// + public int EvasionMax => (int)RawData.api_kaihi[1]; + + /// + /// 対潜最大値 + /// + public int ASWMax => (int)RawData.api_taisen[1]; + + /// + /// 索敵最大値 + /// + public int LOSMax => (int)RawData.api_sakuteki[1]; + + #endregion + + + /// + /// 保護ロックの有無 + /// + public bool IsLocked => (int)RawData.api_locked != 0; + + /// + /// 装備による保護ロックの有無 + /// + public bool IsLockedByEquipment => (int)RawData.api_locked_equip != 0; + + + /// + /// 出撃海域 + /// + public int SallyArea => RawData.api_sally_area() ? (int)RawData.api_sally_area : -1; + + + + /// + /// 艦船のマスターデータへの参照 + /// + public ShipDataMaster MasterShip => KCDatabase.Instance.MasterShips[ShipID]; + + + /// + /// 入渠中のドックID 非入渠時は-1 + /// + public int RepairingDockID => KCDatabase.Instance.Docks.Values.FirstOrDefault(dock => dock.ShipID == MasterID)?.DockID ?? -1; + + + /// + /// 所属艦隊 -1=なし + /// + public int Fleet => KCDatabase.Instance.Fleet.Fleets.Values.FirstOrDefault(f => f.Members.Contains(MasterID))?.FleetID ?? -1; + + + + /// + /// 所属艦隊及びその位置 + /// ex. 1-3 (位置も1から始まる) + /// 所属していなければ 空文字列 + /// + public string FleetWithIndex + { + get + { + FleetManager fm = KCDatabase.Instance.Fleet; + foreach (var f in fm.Fleets.Values) + { + int index = f.Members.IndexOf(MasterID); + if (index != -1) + { + return $"{f.FleetID}-{index + 1}"; + } + } + return ""; + } - } + } - /// - /// ケッコン済みかどうか - /// - public bool IsMarried => Level > 99; + /// + /// ケッコン済みかどうか + /// + public bool IsMarried => Level > 99; - /// - /// 次の改装まで必要な経験値 - /// - public int ExpNextRemodel - { - get - { - ShipDataMaster master = MasterShip; - if (master.RemodelAfterShipID <= 0) - return 0; - return Math.Max(ExpTable.ShipExp[master.RemodelAfterLevel].Total - ExpTotal, 0); - } - } + /// + /// 次の改装まで必要な経験値 + /// + public int ExpNextRemodel + { + get + { + ShipDataMaster master = MasterShip; + if (master.RemodelAfterShipID <= 0) + return 0; + return Math.Max(ExpTable.ShipExp[master.RemodelAfterLevel].Total - ExpTotal, 0); + } + } - /// - /// 艦名 - /// - public string Name => MasterShip.Name; + /// + /// 艦名 + /// + public string Name => MasterShip.Name; - /// - /// 艦名(レベルを含む) - /// - public string NameWithLevel => $"{MasterShip.Name} Lv. {Level}"; + /// + /// 艦名(レベルを含む) + /// + public string NameWithLevel => $"{MasterShip.Name} Lv. {Level}"; - /// - /// HP/HPmax - /// - public double HPRate => HPMax > 0 ? (double)HPCurrent / HPMax : 0; + /// + /// HP/HPmax + /// + public double HPRate => HPMax > 0 ? (double)HPCurrent / HPMax : 0; - /// - /// 最大搭載燃料 - /// - public int FuelMax => MasterShip.Fuel; + /// + /// 最大搭載燃料 + /// + public int FuelMax => MasterShip.Fuel; - /// - /// 最大搭載弾薬 - /// - public int AmmoMax => MasterShip.Ammo; + /// + /// 最大搭載弾薬 + /// + public int AmmoMax => MasterShip.Ammo; - /// - /// 燃料残量割合 - /// - public double FuelRate => (double)Fuel / Math.Max(FuelMax, 1); + /// + /// 燃料残量割合 + /// + public double FuelRate => (double)Fuel / Math.Max(FuelMax, 1); - /// - /// 弾薬残量割合 - /// - public double AmmoRate => (double)Ammo / Math.Max(AmmoMax, 1); + /// + /// 弾薬残量割合 + /// + public double AmmoRate => (double)Ammo / Math.Max(AmmoMax, 1); - /// - /// 補給で消費する燃料 - /// - public int SupplyFuel => (FuelMax - Fuel) == 0 ? 0 : Math.Max((int)Math.Floor((FuelMax - Fuel) * (IsMarried ? 0.85 : 1)), 1); + /// + /// 補給で消費する燃料 + /// + public int SupplyFuel => (FuelMax - Fuel) == 0 ? 0 : Math.Max((int)Math.Floor((FuelMax - Fuel) * (IsMarried ? 0.85 : 1)), 1); - /// - /// 補給で消費する弾薬 - /// - public int SupplyAmmo => (AmmoMax - Ammo) == 0 ? 0 : Math.Max((int)Math.Floor((AmmoMax - Ammo) * (IsMarried ? 0.85 : 1)), 1); - - - /// - /// 搭載機残量割合 - /// - public ReadOnlyCollection AircraftRate - { - get - { - double[] airs = new double[_aircraft.Length]; - var airmax = MasterShip.Aircraft; - - for (int i = 0; i < airs.Length; i++) - { - airs[i] = (double)_aircraft[i] / Math.Max(airmax[i], 1); - } - - return Array.AsReadOnly(airs); - } - } - - /// - /// 搭載機残量割合 - /// - public double AircraftTotalRate => (double)AircraftTotal / Math.Max(MasterShip.AircraftTotal, 1); - - - - /// - /// 補強装備スロットが使用可能か - /// - public bool IsExpansionSlotAvailable => ExpansionSlot != 0; - - - - #region ダメージ威力計算 - - /// - /// 航空戦威力 - /// 本来スロットごとのものであるが、ここでは最大火力を採用する - /// - public int AirBattlePower => _airbattlePowers.Max(); - - private int[] _airbattlePowers; - /// - /// 各スロットの航空戦威力 - /// - public ReadOnlyCollection AirBattlePowers => Array.AsReadOnly(_airbattlePowers); - - /// - /// 砲撃威力 - /// - public int ShellingPower { get; private set; } - - //todo: ShellingPower に統合予定 - /// - /// 空撃威力 - /// - public int AircraftPower { get; private set; } - - /// - /// 対潜威力 - /// - public int AntiSubmarinePower { get; private set; } - - /// - /// 雷撃威力 - /// - public int TorpedoPower { get; private set; } - - /// - /// 夜戦威力 - /// - public int NightBattlePower { get; private set; } - - - - /// - /// 装備改修補正(砲撃戦) - /// - private double GetDayBattleEquipmentLevelBonus() - { - - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.MainGunLarge: - case EquipmentTypes.MainGunLarge2: - basepower += Math.Sqrt(slot.Level) * 1.5; - break; - - case EquipmentTypes.Sonar: - case EquipmentTypes.DepthCharge: - basepower += Math.Sqrt(slot.Level) * 0.75; - break; - - case EquipmentTypes.Torpedo: - case EquipmentTypes.SeaplaneRecon: - case EquipmentTypes.RadarSmall: - case EquipmentTypes.RadarLarge: - case EquipmentTypes.SubmarineTorpedo: - break; // → 無視 - - default: - basepower += Math.Sqrt(slot.Level); - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(空撃) - /// - /// - private double GetAircraftEquipmentLevelBonus() - { - - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.SecondaryGun: - basepower += Math.Sqrt(slot.Level); - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(雷撃戦) - /// - private double GetTorpedoEquipmentLevelBonus() - { - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.Torpedo: - case EquipmentTypes.AAGun: - case EquipmentTypes.SubmarineTorpedo: - basepower += Math.Sqrt(slot.Level) * 1.2; - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(対潜) - /// - private double GetAntiSubmarineEquipmentLevelBonus() - { - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.DepthCharge: - case EquipmentTypes.Sonar: - basepower += Math.Sqrt(slot.Level) * 1.2; - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(夜戦) - /// - private double GetNightBattleEquipmentLevelBonus() - { - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.MainGunSmall: - case EquipmentTypes.MainGunMedium: - case EquipmentTypes.MainGunLarge: - case EquipmentTypes.SecondaryGun: - case EquipmentTypes.Torpedo: - case EquipmentTypes.APShell: - case EquipmentTypes.LandingCraft: - case EquipmentTypes.Searchlight: - case EquipmentTypes.SubmarineTorpedo: - case EquipmentTypes.AADirector: - case EquipmentTypes.MainGunLarge2: - case EquipmentTypes.SearchlightLarge: - case EquipmentTypes.SpecialAmphibiousTank: - basepower += Math.Sqrt(slot.Level); - break; - } - } - return basepower; - } - - /// - /// 耐久値による攻撃力補正 - /// - private double GetHPDamageBonus() - { - if (HPRate < 0.25) - return 0.4; - else if (HPRate < 0.5) - return 0.7; - else - return 1.0; - } - - /// - /// 耐久値による攻撃力補正(雷撃戦) - /// - /// - private double GetTorpedoHPDamageBonus() - { - if (HPRate < 0.25) - return 0.0; - else if (HPRate < 0.5) - return 0.8; - else - return 1.0; - } - - /// - /// 交戦形態による威力補正 - /// - private double GetEngagementFormDamageRate(int form) - { - switch (form) - { - case 1: // 同航戦 - default: - return 1.0; - case 2: // 反航戦 - return 0.8; - case 3: // T字有利 - return 1.2; - case 4: // T字不利 - return 0.6; - } - } - - /// - /// 残り弾薬量による威力補正 - /// - private double GetAmmoDamageRate() - { - return Math.Min(Math.Floor(AmmoRate * 100) / 50.0, 1.0); - } - - /// - /// 連合艦隊編成における砲撃戦火力補正 - /// - private double GetCombinedFleetShellingDamageBonus() - { - int fleet = Fleet; - if (fleet == -1 || fleet > 2) - return 0; - - switch (KCDatabase.Instance.Fleet.CombinedFlag) - { - case 1: //機動部隊 - if (fleet == 1) - return +2; - else - return +10; - - case 2: //水上部隊 - if (fleet == 1) - return +10; - else - return -5; - - case 3: //輸送部隊 - if (fleet == 1) - return -5; - else - return +10; - - default: - return 0; - } - } - - /// - /// 連合艦隊編成における雷撃戦火力補正 - /// - private double GetCombinedFleetTorpedoDamageBonus() - { - int fleet = Fleet; - if (fleet == -1 || fleet > 2) - return 0; - - if (KCDatabase.Instance.Fleet.CombinedFlag == 0) - return 0; - - return -5; - } - - /// - /// 軽巡軽量砲補正 - /// - private double GetLightCruiserDamageBonus() - { - if (MasterShip.ShipType == ShipTypes.LightCruiser || - MasterShip.ShipType == ShipTypes.TorpedoCruiser || - MasterShip.ShipType == ShipTypes.TrainingCruiser) - { - - int single = 0; - int twin = 0; - - foreach (var slot in AllSlotMaster) - { - if (slot == -1) continue; - - switch (slot) - { - case 4: // 14cm単装砲 - case 11: // 15.2cm単装砲 - single++; - break; - case 65: // 15.2cm連装砲 - case 119: // 14cm連装砲 - case 139: // 15.2cm連装砲改 - twin++; - break; - } - } - - return Math.Sqrt(twin) * 2.0 + Math.Sqrt(single); - } - - return 0; - } - - /// - /// イタリア重巡砲補正 - /// - /// - private double GetItalianDamageBonus() - { - switch (ShipID) - { - case 448: // Zara - case 358: // 改 - case 496: // due - case 449: // Pola - case 361: // 改 - return Math.Sqrt(AllSlotMaster.Count(id => id == 162)); // √( 203mm/53 連装砲 装備数 ) - - default: - return 0; - } - } - - private double CapDamage(double damage, int max) - { - if (damage < max) - return damage; - else - return max + Math.Sqrt(damage - max); - } - - - /// - /// 航空戦での威力を求めます。 - /// - /// スロットのインデックス。 0 起点です。 - private int CalculateAirBattlePower(int slotIndex) - { - double basepower = 0; - var slots = AllSlotInstance; - - var eq = SlotInstance[slotIndex]; - - if (eq == null || _aircraft[slotIndex] == 0) - return 0; - - switch (eq.MasterEquipment.CategoryType) - { - case EquipmentTypes.CarrierBasedBomber: - case EquipmentTypes.SeaplaneBomber: - case EquipmentTypes.JetBomber: // 通常航空戦においては /√2 されるが、とりあえず考えない - basepower = eq.MasterEquipment.Bomber * Math.Sqrt(_aircraft[slotIndex]) + 25; - break; - case EquipmentTypes.CarrierBasedTorpedo: - case EquipmentTypes.JetTorpedo: - // 150% 補正を引いたとする - basepower = (eq.MasterEquipment.Torpedo * Math.Sqrt(_aircraft[slotIndex]) + 25) * 1.5; - break; - default: - return 0; - } - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 150)); - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 砲撃戦での砲撃威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateShellingPower(int engagementForm = 1) - { - var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); - if (attackKind == DayAttackKind.AirAttack || attackKind == DayAttackKind.CutinAirAttack) - return 0; - - - double basepower = FirepowerTotal + GetDayBattleEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus() + 5; - - basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); - - // キャップ - basepower = Math.Floor(CapDamage(basepower, 180)); - - // 弾着観測射撃 - switch (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1)) - { - case DayAttackKind.DoubleShelling: - case DayAttackKind.CutinMainRadar: - basepower *= 1.2; - break; - case DayAttackKind.CutinMainSub: - basepower *= 1.1; - break; - case DayAttackKind.CutinMainAP: - basepower *= 1.3; - break; - case DayAttackKind.CutinMainMain: - basepower *= 1.5; - break; - } - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 砲撃戦での空撃威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateAircraftPower(int engagementForm = 1) - { - var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); - if (attackKind != DayAttackKind.AirAttack && attackKind != DayAttackKind.CutinAirAttack) - return 0; - - - double basepower = Math.Floor((FirepowerTotal + TorpedoTotal + Math.Floor(BomberTotal * 1.3) + GetAircraftEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus()) * 1.5) + 55; - - basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - // キャップ - basepower = Math.Floor(CapDamage(basepower, 180)); - - - // 空母カットイン - if (attackKind == DayAttackKind.CutinAirAttack) - { - var kind = Calculator.GetDayAirAttackCutinKind(SlotInstanceMaster); - switch (kind) - { - case DayAirAttackCutinKind.FighterBomberAttacker: - basepower *= 1.25; - break; - - case DayAirAttackCutinKind.BomberBomberAttacker: - basepower *= 1.20; - break; - - case DayAirAttackCutinKind.BomberAttacker: - basepower *= 1.15; - break; - } - } - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 砲撃戦での対潜威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateAntiSubmarinePower(int engagementForm = 1) - { - if (!CanAttackSubmarine) - return 0; - - double eqpower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.CarrierBasedBomber: - case EquipmentTypes.CarrierBasedTorpedo: - case EquipmentTypes.SeaplaneBomber: - case EquipmentTypes.Sonar: - case EquipmentTypes.DepthCharge: - case EquipmentTypes.Autogyro: - case EquipmentTypes.ASPatrol: - case EquipmentTypes.SonarLarge: - eqpower += slot.MasterEquipment.ASW; - break; - } - } - - double basepower = Math.Sqrt(ASWBase) * 2 + eqpower * 1.5 + GetAntiSubmarineEquipmentLevelBonus(); - if (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, 126, false) == DayAttackKind.AirAttack) - { //126=伊168; 対潜攻撃が空撃なら - basepower += 8; - } - else - { //爆雷攻撃なら - basepower += 13; - } - - - basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - - //対潜シナジー - - int depthChargeCount = 0; - int depthChargeProjectorCount = 0; - int sonarCount = 0; // ソナーと大型ソナーの合算 - int largeSonarCount = 0; - - foreach (var slot in AllSlotInstanceMaster) - { - if (slot == null) - continue; - - switch (slot.CategoryType) - { - case EquipmentTypes.Sonar: - sonarCount++; - break; - case EquipmentTypes.DepthCharge: - if (slot.IsDepthCharge) - depthChargeCount++; - else - depthChargeProjectorCount++; - break; - case EquipmentTypes.SonarLarge: - largeSonarCount++; - sonarCount++; - break; - } - } - - double projector_sonar = depthChargeProjectorCount > 0 && sonarCount > 0 ? 1.15 : 1; - double charge_projector = depthChargeCount > 0 && depthChargeProjectorCount > 0 ? 1.1 : 1; - double charge_sonar = (!(projector_sonar > 1 && charge_projector > 1 && largeSonarCount > 0) && depthChargeCount > 0 && sonarCount > 0) ? 0.15 : 0; - - basepower *= projector_sonar * (charge_projector + charge_sonar); - - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 150)); - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 雷撃戦での威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateTorpedoPower(int engagementForm = 1) - { - if (TorpedoBase == 0) - return 0; //雷撃不能艦は除外 - - double basepower = TorpedoTotal + GetTorpedoEquipmentLevelBonus() + GetCombinedFleetTorpedoDamageBonus() + 5; - - basepower *= GetTorpedoHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 150)); - - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 夜戦での威力を求めます。 - /// - private int CalculateNightBattlePower() - { - var kind = Calculator.GetNightAttackKind(AllSlotMaster.ToArray(), ShipID, -1); - double basepower = 0; - - if (kind == NightAttackKind.CutinAirAttack) - { - var airs = SlotInstance.Zip(Aircraft, (eq, count) => new { eq, master = eq?.MasterEquipment, count }).Where(a => a.eq != null); - - basepower = FirepowerBase + - airs.Where(p => p.master.IsNightAircraft) - .Sum(p => p.master.Firepower + p.master.Torpedo + - 3 * p.count + - 0.45 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)) + - airs.Where(p => p.master.IsSwordfish || p.master.EquipmentID == 154) // 零戦62型(爆戦/岩井隊) - .Sum(p => p.master.Firepower + p.master.Torpedo + - 0.3 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)); - - } - else if (ShipID == 515 || ShipID == 393) - { // Ark Royal (改) - basepower = FirepowerBase + SlotInstanceMaster.Where(eq => eq?.IsSwordfish ?? false).Sum(eq => eq.Firepower + eq.Torpedo); - } - else - { - basepower = FirepowerTotal + TorpedoTotal + GetNightBattleEquipmentLevelBonus(); - } - - - basepower *= GetHPDamageBonus(); - - switch (kind) - { - case NightAttackKind.DoubleShelling: - basepower *= 1.2; - break; - - case NightAttackKind.CutinMainTorpedo: - basepower *= 1.3; - break; - - case NightAttackKind.CutinTorpedoTorpedo: - { - switch (Calculator.GetNightTorpedoCutinKind(AllSlotInstanceMaster, ShipID, -1)) - { - case NightTorpedoCutinKind.LateModelTorpedoSubmarineEquipment: - basepower *= 1.75; - break; - case NightTorpedoCutinKind.LateModelTorpedo2: - basepower *= 1.6; - break; - default: - basepower *= 1.5; - break; - } - } - break; - - case NightAttackKind.CutinMainSub: - basepower *= 1.75; - break; - - case NightAttackKind.CutinMainMain: - basepower *= 2.0; - break; - - case NightAttackKind.CutinAirAttack: - { - int nightFighter = SlotInstanceMaster.Count(eq => eq?.IsNightFighter ?? false); - int nightAttacker = SlotInstanceMaster.Count(eq => eq?.IsNightAttacker ?? false); - - if (nightFighter >= 2 && nightAttacker >= 1) - basepower *= 1.25; - else if (nightFighter >= 1 && nightAttacker >= 1) - basepower *= 1.2; - else - basepower *= 1.18; - } - break; - - case NightAttackKind.CutinTorpedoRadar: - basepower *= 1.3; - break; - - case NightAttackKind.CutinTorpedoPicket: - basepower *= 1.25; - break; - } - - basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 300)); - - - return (int)(basepower * GetAmmoDamageRate()); - } - - - /// - /// 威力系の計算をまとめて行い、プロパティを更新します。 - /// - private void CalculatePowers() - { - - int form = Utility.Configuration.Config.Control.PowerEngagementForm; - - _airbattlePowers = Slot.Select((_, i) => CalculateAirBattlePower(i)).ToArray(); - ShellingPower = CalculateShellingPower(form); - AircraftPower = CalculateAircraftPower(form); - AntiSubmarinePower = CalculateAntiSubmarinePower(form); - TorpedoPower = CalculateTorpedoPower(form); - NightBattlePower = CalculateNightBattlePower(); - - } - - - #endregion - - - - /// - /// 対潜攻撃可能か - /// - public bool CanAttackSubmarine - { - get - { - switch (MasterShip.ShipType) - { - case ShipTypes.Escort: - case ShipTypes.Destroyer: - case ShipTypes.LightCruiser: - case ShipTypes.TorpedoCruiser: - case ShipTypes.TrainingCruiser: - case ShipTypes.FleetOiler: - return ASWBase > 0; - - case ShipTypes.AviationCruiser: - case ShipTypes.LightAircraftCarrier: - case ShipTypes.AviationBattleship: - case ShipTypes.SeaplaneTender: - case ShipTypes.AmphibiousAssaultShip: - return AllSlotInstanceMaster.Any(eq => eq != null && eq.IsAntiSubmarineAircraft); - - default: - return false; - } - } - } - - /// - /// 開幕対潜攻撃可能か - /// - public bool CanOpeningASW - { - get - { - if (!CanAttackSubmarine) - return false; - - if (ShipID == 141) // 五十鈴改二 - return true; - - var eqs = AllSlotInstance.Where(eq => eq != null); - - if (ShipID == 380 || ShipID == 529) // 大鷹改(二) - { - if (ASWTotal >= 65) // 注: Lv. 1時点で対潜が 65 以上であるため、現時点では無条件に達成可能 - return true; - } - - if (ShipID == 526) // 大鷹 - { - // 対潜 7 以上の艦上攻撃機 - bool hasASWTorp = eqs.Any(eq => eq.MasterEquipment.CategoryType == EquipmentTypes.CarrierBasedTorpedo && eq.MasterEquipment.ASW >= 7); - if (hasASWTorp && ASWTotal >= 65) - return true; - } - - bool hasSonar = eqs.Any(eq => eq.MasterEquipment.IsSonar); - bool needSonar = !( - MasterShip.ShipType == ShipTypes.Escort && - ASWTotal >= 75 && - (ASWTotal - ASWBase) >= 4); - - if (needSonar && !hasSonar) - return false; - - if (MasterShip.ShipType == ShipTypes.Escort) - return ASWTotal >= 60; - else - return ASWTotal >= 100; - } - } - - - /// - /// 夜戦攻撃可能か - /// - public bool CanAttackAtNight - { - get - { - var master = MasterShip; - - if (HPRate <= 0.25) - return false; - - if (master.FirepowerMin + master.TorpedoMin > 0) - return true; - - // Ark Royal(改) - if (master.ShipID == 515 || master.ShipID == 393) - { - if (AllSlotInstanceMaster.Any(eq => eq != null && eq.IsSwordfish)) - return true; - } - - if (master.IsAircraftCarrier) - { - // 装甲空母ではなく、中破以上の被ダメージ - if (master.ShipType != ShipTypes.ArmoredAircraftCarrier && HPRate <= 0.5) - return false; - - // Saratoga Mk.II は不要 - bool hasNightPersonnel = master.ShipID == 545 || - AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAviationPersonnel); - - bool hasNightAircraft = AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAircraft); - - if (hasNightPersonnel && hasNightAircraft) - return true; - } - - return false; - } - } - - - /// - /// 発動可能なダメコンのID -1=なし, 42=要員, 43=女神 - /// - public int DamageControlID - { - get - { - if (ExpansionSlotMaster == 42 || ExpansionSlotMaster == 43) - return ExpansionSlotMaster; - - foreach (var eq in SlotMaster) - { - if (eq == 42 || eq == 43) - return eq; - } - - return -1; - } - } - - - - public int ID => MasterID; - public override string ToString() => $"[{MasterID}] {NameWithLevel}"; - - - public override void LoadFromResponse(string apiname, dynamic data) - { - - switch (apiname) - { - default: - base.LoadFromResponse(apiname, (object)data); - - HPCurrent = (int)RawData.api_nowhp; - Fuel = (int)RawData.api_fuel; - Ammo = (int)RawData.api_bull; - Condition = (int)RawData.api_cond; - Slot = Array.AsReadOnly((int[])RawData.api_slot); - ExpansionSlot = (int)RawData.api_slot_ex; - _aircraft = (int[])RawData.api_onslot; - _modernized = (int[])RawData.api_kyouka; - break; - - case "api_req_hokyu/charge": - Fuel = (int)data.api_fuel; - Ammo = (int)data.api_bull; - _aircraft = (int[])data.api_onslot; - break; - - case "api_req_kaisou/slot_exchange_index": - Slot = Array.AsReadOnly((int[])data.api_slot); - break; - } + /// + /// 補給で消費する弾薬 + /// + public int SupplyAmmo => (AmmoMax - Ammo) == 0 ? 0 : Math.Max((int)Math.Floor((AmmoMax - Ammo) * (IsMarried ? 0.85 : 1)), 1); + + + /// + /// 搭載機残量割合 + /// + public ReadOnlyCollection AircraftRate + { + get + { + double[] airs = new double[_aircraft.Length]; + var airmax = MasterShip.Aircraft; + + for (int i = 0; i < airs.Length; i++) + { + airs[i] = (double)_aircraft[i] / Math.Max(airmax[i], 1); + } + + return Array.AsReadOnly(airs); + } + } + + /// + /// 搭載機残量割合 + /// + public double AircraftTotalRate => (double)AircraftTotal / Math.Max(MasterShip.AircraftTotal, 1); + + + + /// + /// 補強装備スロットが使用可能か + /// + public bool IsExpansionSlotAvailable => ExpansionSlot != 0; + + + + #region ダメージ威力計算 + + /// + /// 航空戦威力 + /// 本来スロットごとのものであるが、ここでは最大火力を採用する + /// + public int AirBattlePower => _airbattlePowers.Max(); + + private int[] _airbattlePowers; + /// + /// 各スロットの航空戦威力 + /// + public ReadOnlyCollection AirBattlePowers => Array.AsReadOnly(_airbattlePowers); + + /// + /// 砲撃威力 + /// + public int ShellingPower { get; private set; } + + //todo: ShellingPower に統合予定 + /// + /// 空撃威力 + /// + public int AircraftPower { get; private set; } + + /// + /// 対潜威力 + /// + public int AntiSubmarinePower { get; private set; } + + /// + /// 雷撃威力 + /// + public int TorpedoPower { get; private set; } + + /// + /// 夜戦威力 + /// + public int NightBattlePower { get; private set; } + + + + /// + /// 装備改修補正(砲撃戦) + /// + private double GetDayBattleEquipmentLevelBonus() + { + + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.MainGunLarge: + case EquipmentTypes.MainGunLarge2: + basepower += Math.Sqrt(slot.Level) * 1.5; + break; + + case EquipmentTypes.Sonar: + case EquipmentTypes.DepthCharge: + basepower += Math.Sqrt(slot.Level) * 0.75; + break; + + case EquipmentTypes.Torpedo: + case EquipmentTypes.SeaplaneRecon: + case EquipmentTypes.RadarSmall: + case EquipmentTypes.RadarLarge: + case EquipmentTypes.SubmarineTorpedo: + break; // → 無視 + + default: + basepower += Math.Sqrt(slot.Level); + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(空撃) + /// + /// + private double GetAircraftEquipmentLevelBonus() + { + + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.SecondaryGun: + basepower += Math.Sqrt(slot.Level); + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(雷撃戦) + /// + private double GetTorpedoEquipmentLevelBonus() + { + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.Torpedo: + case EquipmentTypes.AAGun: + case EquipmentTypes.SubmarineTorpedo: + basepower += Math.Sqrt(slot.Level) * 1.2; + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(対潜) + /// + private double GetAntiSubmarineEquipmentLevelBonus() + { + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.DepthCharge: + case EquipmentTypes.Sonar: + basepower += Math.Sqrt(slot.Level) * 1.2; + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(夜戦) + /// + private double GetNightBattleEquipmentLevelBonus() + { + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.MainGunSmall: + case EquipmentTypes.MainGunMedium: + case EquipmentTypes.MainGunLarge: + case EquipmentTypes.SecondaryGun: + case EquipmentTypes.Torpedo: + case EquipmentTypes.APShell: + case EquipmentTypes.LandingCraft: + case EquipmentTypes.Searchlight: + case EquipmentTypes.SubmarineTorpedo: + case EquipmentTypes.AADirector: + case EquipmentTypes.MainGunLarge2: + case EquipmentTypes.SearchlightLarge: + case EquipmentTypes.SpecialAmphibiousTank: + basepower += Math.Sqrt(slot.Level); + break; + } + } + return basepower; + } + + /// + /// 耐久値による攻撃力補正 + /// + private double GetHPDamageBonus() + { + if (HPRate < 0.25) + return 0.4; + else if (HPRate < 0.5) + return 0.7; + else + return 1.0; + } + + /// + /// 耐久値による攻撃力補正(雷撃戦) + /// + /// + private double GetTorpedoHPDamageBonus() + { + if (HPRate < 0.25) + return 0.0; + else if (HPRate < 0.5) + return 0.8; + else + return 1.0; + } + + /// + /// 交戦形態による威力補正 + /// + private double GetEngagementFormDamageRate(int form) + { + switch (form) + { + case 1: // 同航戦 + default: + return 1.0; + case 2: // 反航戦 + return 0.8; + case 3: // T字有利 + return 1.2; + case 4: // T字不利 + return 0.6; + } + } + + /// + /// 残り弾薬量による威力補正 + /// + private double GetAmmoDamageRate() + { + return Math.Min(Math.Floor(AmmoRate * 100) / 50.0, 1.0); + } + + /// + /// 連合艦隊編成における砲撃戦火力補正 + /// + private double GetCombinedFleetShellingDamageBonus() + { + int fleet = Fleet; + if (fleet == -1 || fleet > 2) + return 0; + + switch (KCDatabase.Instance.Fleet.CombinedFlag) + { + case 1: //機動部隊 + if (fleet == 1) + return +2; + else + return +10; + + case 2: //水上部隊 + if (fleet == 1) + return +10; + else + return -5; + + case 3: //輸送部隊 + if (fleet == 1) + return -5; + else + return +10; + + default: + return 0; + } + } + + /// + /// 連合艦隊編成における雷撃戦火力補正 + /// + private double GetCombinedFleetTorpedoDamageBonus() + { + int fleet = Fleet; + if (fleet == -1 || fleet > 2) + return 0; + + if (KCDatabase.Instance.Fleet.CombinedFlag == 0) + return 0; + + return -5; + } + + /// + /// 軽巡軽量砲補正 + /// + private double GetLightCruiserDamageBonus() + { + if (MasterShip.ShipType == ShipTypes.LightCruiser || + MasterShip.ShipType == ShipTypes.TorpedoCruiser || + MasterShip.ShipType == ShipTypes.TrainingCruiser) + { + + int single = 0; + int twin = 0; + + foreach (var slot in AllSlotMaster) + { + if (slot == -1) continue; + + switch (slot) + { + case 4: // 14cm単装砲 + case 11: // 15.2cm単装砲 + single++; + break; + case 65: // 15.2cm連装砲 + case 119: // 14cm連装砲 + case 139: // 15.2cm連装砲改 + twin++; + break; + } + } + + return Math.Sqrt(twin) * 2.0 + Math.Sqrt(single); + } + + return 0; + } + + /// + /// イタリア重巡砲補正 + /// + /// + private double GetItalianDamageBonus() + { + switch (ShipID) + { + case 448: // Zara + case 358: // 改 + case 496: // due + case 449: // Pola + case 361: // 改 + return Math.Sqrt(AllSlotMaster.Count(id => id == 162)); // √( 203mm/53 連装砲 装備数 ) + + default: + return 0; + } + } + + private double CapDamage(double damage, int max) + { + if (damage < max) + return damage; + else + return max + Math.Sqrt(damage - max); + } + + + /// + /// 航空戦での威力を求めます。 + /// + /// スロットのインデックス。 0 起点です。 + private int CalculateAirBattlePower(int slotIndex) + { + double basepower = 0; + var slots = AllSlotInstance; + + var eq = SlotInstance[slotIndex]; + + if (eq == null || _aircraft[slotIndex] == 0) + return 0; + + switch (eq.MasterEquipment.CategoryType) + { + case EquipmentTypes.CarrierBasedBomber: + case EquipmentTypes.SeaplaneBomber: + case EquipmentTypes.JetBomber: // 通常航空戦においては /√2 されるが、とりあえず考えない + basepower = eq.MasterEquipment.Bomber * Math.Sqrt(_aircraft[slotIndex]) + 25; + break; + case EquipmentTypes.CarrierBasedTorpedo: + case EquipmentTypes.JetTorpedo: + // 150% 補正を引いたとする + basepower = (eq.MasterEquipment.Torpedo * Math.Sqrt(_aircraft[slotIndex]) + 25) * 1.5; + break; + default: + return 0; + } + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 150)); + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 砲撃戦での砲撃威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateShellingPower(int engagementForm = 1) + { + var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); + if (attackKind == DayAttackKind.AirAttack || attackKind == DayAttackKind.CutinAirAttack) + return 0; + + + double basepower = FirepowerTotal + GetDayBattleEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus() + 5; + + basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); + + // キャップ + basepower = Math.Floor(CapDamage(basepower, 180)); + + // 弾着観測射撃 + switch (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1)) + { + case DayAttackKind.DoubleShelling: + case DayAttackKind.CutinMainRadar: + basepower *= 1.2; + break; + case DayAttackKind.CutinMainSub: + basepower *= 1.1; + break; + case DayAttackKind.CutinMainAP: + basepower *= 1.3; + break; + case DayAttackKind.CutinMainMain: + basepower *= 1.5; + break; + } + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 砲撃戦での空撃威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateAircraftPower(int engagementForm = 1) + { + var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); + if (attackKind != DayAttackKind.AirAttack && attackKind != DayAttackKind.CutinAirAttack) + return 0; + + + double basepower = Math.Floor((FirepowerTotal + TorpedoTotal + Math.Floor(BomberTotal * 1.3) + GetAircraftEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus()) * 1.5) + 55; + + basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + // キャップ + basepower = Math.Floor(CapDamage(basepower, 180)); + + + // 空母カットイン + if (attackKind == DayAttackKind.CutinAirAttack) + { + var kind = Calculator.GetDayAirAttackCutinKind(SlotInstanceMaster); + switch (kind) + { + case DayAirAttackCutinKind.FighterBomberAttacker: + basepower *= 1.25; + break; + + case DayAirAttackCutinKind.BomberBomberAttacker: + basepower *= 1.20; + break; + + case DayAirAttackCutinKind.BomberAttacker: + basepower *= 1.15; + break; + } + } + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 砲撃戦での対潜威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateAntiSubmarinePower(int engagementForm = 1) + { + if (!CanAttackSubmarine) + return 0; + + double eqpower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.CarrierBasedBomber: + case EquipmentTypes.CarrierBasedTorpedo: + case EquipmentTypes.SeaplaneBomber: + case EquipmentTypes.Sonar: + case EquipmentTypes.DepthCharge: + case EquipmentTypes.Autogyro: + case EquipmentTypes.ASPatrol: + case EquipmentTypes.SonarLarge: + eqpower += slot.MasterEquipment.ASW; + break; + } + } + + double basepower = Math.Sqrt(ASWBase) * 2 + eqpower * 1.5 + GetAntiSubmarineEquipmentLevelBonus(); + if (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, 126, false) == DayAttackKind.AirAttack) + { //126=伊168; 対潜攻撃が空撃なら + basepower += 8; + } + else + { //爆雷攻撃なら + basepower += 13; + } + + + basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + + //対潜シナジー + + int depthChargeCount = 0; + int depthChargeProjectorCount = 0; + int sonarCount = 0; // ソナーと大型ソナーの合算 + int largeSonarCount = 0; + + foreach (var slot in AllSlotInstanceMaster) + { + if (slot == null) + continue; + + switch (slot.CategoryType) + { + case EquipmentTypes.Sonar: + sonarCount++; + break; + case EquipmentTypes.DepthCharge: + if (slot.IsDepthCharge) + depthChargeCount++; + else + depthChargeProjectorCount++; + break; + case EquipmentTypes.SonarLarge: + largeSonarCount++; + sonarCount++; + break; + } + } + + double projector_sonar = depthChargeProjectorCount > 0 && sonarCount > 0 ? 1.15 : 1; + double charge_projector = depthChargeCount > 0 && depthChargeProjectorCount > 0 ? 1.1 : 1; + double charge_sonar = (!(projector_sonar > 1 && charge_projector > 1 && largeSonarCount > 0) && depthChargeCount > 0 && sonarCount > 0) ? 0.15 : 0; + + basepower *= projector_sonar * (charge_projector + charge_sonar); + + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 150)); + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 雷撃戦での威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateTorpedoPower(int engagementForm = 1) + { + if (TorpedoBase == 0) + return 0; //雷撃不能艦は除外 + + double basepower = TorpedoTotal + GetTorpedoEquipmentLevelBonus() + GetCombinedFleetTorpedoDamageBonus() + 5; + + basepower *= GetTorpedoHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 150)); + + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 夜戦での威力を求めます。 + /// + private int CalculateNightBattlePower() + { + var kind = Calculator.GetNightAttackKind(AllSlotMaster.ToArray(), ShipID, -1); + double basepower = 0; + + if (kind == NightAttackKind.CutinAirAttack) + { + var airs = SlotInstance.Zip(Aircraft, (eq, count) => new { eq, master = eq?.MasterEquipment, count }).Where(a => a.eq != null); + + basepower = FirepowerBase + + airs.Where(p => p.master.IsNightAircraft) + .Sum(p => p.master.Firepower + p.master.Torpedo + + 3 * p.count + + 0.45 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)) + + airs.Where(p => p.master.IsSwordfish || p.master.EquipmentID == 154) // 零戦62型(爆戦/岩井隊) + .Sum(p => p.master.Firepower + p.master.Torpedo + + 0.3 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)); + + } + else if (ShipID == 515 || ShipID == 393) + { // Ark Royal (改) + basepower = FirepowerBase + SlotInstanceMaster.Where(eq => eq?.IsSwordfish ?? false).Sum(eq => eq.Firepower + eq.Torpedo); + } + else + { + basepower = FirepowerTotal + TorpedoTotal + GetNightBattleEquipmentLevelBonus(); + } + + + basepower *= GetHPDamageBonus(); + + switch (kind) + { + case NightAttackKind.DoubleShelling: + basepower *= 1.2; + break; + + case NightAttackKind.CutinMainTorpedo: + basepower *= 1.3; + break; + + case NightAttackKind.CutinTorpedoTorpedo: + { + switch (Calculator.GetNightTorpedoCutinKind(AllSlotInstanceMaster, ShipID, -1)) + { + case NightTorpedoCutinKind.LateModelTorpedoSubmarineEquipment: + basepower *= 1.75; + break; + case NightTorpedoCutinKind.LateModelTorpedo2: + basepower *= 1.6; + break; + default: + basepower *= 1.5; + break; + } + } + break; + + case NightAttackKind.CutinMainSub: + basepower *= 1.75; + break; + + case NightAttackKind.CutinMainMain: + basepower *= 2.0; + break; + + case NightAttackKind.CutinAirAttack: + { + int nightFighter = SlotInstanceMaster.Count(eq => eq?.IsNightFighter ?? false); + int nightAttacker = SlotInstanceMaster.Count(eq => eq?.IsNightAttacker ?? false); + + if (nightFighter >= 2 && nightAttacker >= 1) + basepower *= 1.25; + else if (nightFighter >= 1 && nightAttacker >= 1) + basepower *= 1.2; + else + basepower *= 1.18; + } + break; + + case NightAttackKind.CutinTorpedoRadar: + if (ShipID == 543 && AllSlotInstanceMaster.Any(eq => eq?.EquipmentID == 267)) // 長波改二 + 12.7cm連装砲D型改二 + basepower *= 1.625; + else + basepower *= 1.3; + break; + + case NightAttackKind.CutinTorpedoPicket: + basepower *= 1.25; + break; + } + + basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 300)); + + + return (int)(basepower * GetAmmoDamageRate()); + } + + + /// + /// 威力系の計算をまとめて行い、プロパティを更新します。 + /// + private void CalculatePowers() + { + + int form = Utility.Configuration.Config.Control.PowerEngagementForm; + + _airbattlePowers = Slot.Select((_, i) => CalculateAirBattlePower(i)).ToArray(); + ShellingPower = CalculateShellingPower(form); + AircraftPower = CalculateAircraftPower(form); + AntiSubmarinePower = CalculateAntiSubmarinePower(form); + TorpedoPower = CalculateTorpedoPower(form); + NightBattlePower = CalculateNightBattlePower(); + + } + + + #endregion + + + + /// + /// 対潜攻撃可能か + /// + public bool CanAttackSubmarine + { + get + { + switch (MasterShip.ShipType) + { + case ShipTypes.Escort: + case ShipTypes.Destroyer: + case ShipTypes.LightCruiser: + case ShipTypes.TorpedoCruiser: + case ShipTypes.TrainingCruiser: + case ShipTypes.FleetOiler: + return ASWBase > 0; + + case ShipTypes.AviationCruiser: + case ShipTypes.LightAircraftCarrier: + case ShipTypes.AviationBattleship: + case ShipTypes.SeaplaneTender: + case ShipTypes.AmphibiousAssaultShip: + return AllSlotInstanceMaster.Any(eq => eq != null && eq.IsAntiSubmarineAircraft); + + default: + return false; + } + } + } + + /// + /// 開幕対潜攻撃可能か + /// + public bool CanOpeningASW + { + get + { + if (!CanAttackSubmarine) + return false; + + if (ShipID == 141) // 五十鈴改二 + return true; + + var eqs = AllSlotInstance.Where(eq => eq != null); + + if (ShipID == 380 || ShipID == 529) // 大鷹改(二) + { + if (ASWTotal >= 65) // 注: Lv. 1時点で対潜が 65 以上であるため、現時点では無条件に達成可能 + return true; + } + + if (ShipID == 526) // 大鷹 + { + // 対潜 7 以上の艦上攻撃機 + bool hasASWTorp = eqs.Any(eq => eq.MasterEquipment.CategoryType == EquipmentTypes.CarrierBasedTorpedo && eq.MasterEquipment.ASW >= 7); + if (hasASWTorp && ASWTotal >= 65) + return true; + } + + bool hasSonar = eqs.Any(eq => eq.MasterEquipment.IsSonar); + bool needSonar = !( + MasterShip.ShipType == ShipTypes.Escort && + ASWTotal >= 75 && + (ASWTotal - ASWBase) >= 4); + + if (needSonar && !hasSonar) + return false; + + if (MasterShip.ShipType == ShipTypes.Escort) + return ASWTotal >= 60; + else + return ASWTotal >= 100; + } + } + + + /// + /// 夜戦攻撃可能か + /// + public bool CanAttackAtNight + { + get + { + var master = MasterShip; + + if (HPRate <= 0.25) + return false; + + if (master.FirepowerMin + master.TorpedoMin > 0) + return true; + + // Ark Royal(改) + if (master.ShipID == 515 || master.ShipID == 393) + { + if (AllSlotInstanceMaster.Any(eq => eq != null && eq.IsSwordfish)) + return true; + } + + if (master.IsAircraftCarrier) + { + // 装甲空母ではなく、中破以上の被ダメージ + if (master.ShipType != ShipTypes.ArmoredAircraftCarrier && HPRate <= 0.5) + return false; + + // Saratoga Mk.II は不要 + bool hasNightPersonnel = master.ShipID == 545 || + AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAviationPersonnel); + + bool hasNightAircraft = AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAircraft); + + if (hasNightPersonnel && hasNightAircraft) + return true; + } + + return false; + } + } + + + /// + /// 発動可能なダメコンのID -1=なし, 42=要員, 43=女神 + /// + public int DamageControlID + { + get + { + if (ExpansionSlotMaster == 42 || ExpansionSlotMaster == 43) + return ExpansionSlotMaster; + + foreach (var eq in SlotMaster) + { + if (eq == 42 || eq == 43) + return eq; + } + + return -1; + } + } + + + + public int ID => MasterID; + public override string ToString() => $"[{MasterID}] {NameWithLevel}"; + + + public override void LoadFromResponse(string apiname, dynamic data) + { + + switch (apiname) + { + default: + base.LoadFromResponse(apiname, (object)data); + + HPCurrent = (int)RawData.api_nowhp; + Fuel = (int)RawData.api_fuel; + Ammo = (int)RawData.api_bull; + Condition = (int)RawData.api_cond; + Slot = Array.AsReadOnly((int[])RawData.api_slot); + ExpansionSlot = (int)RawData.api_slot_ex; + _aircraft = (int[])RawData.api_onslot; + _modernized = (int[])RawData.api_kyouka; + break; + + case "api_req_hokyu/charge": + Fuel = (int)data.api_fuel; + Ammo = (int)data.api_bull; + _aircraft = (int[])data.api_onslot; + break; + + case "api_req_kaisou/slot_exchange_index": + Slot = Array.AsReadOnly((int[])data.api_slot); + break; + } - CalculatePowers(); - } - - - public override void LoadFromRequest(string apiname, Dictionary data) - { - base.LoadFromRequest(apiname, data); + CalculatePowers(); + } + + + public override void LoadFromRequest(string apiname, Dictionary data) + { + base.LoadFromRequest(apiname, data); - KCDatabase db = KCDatabase.Instance; + KCDatabase db = KCDatabase.Instance; - switch (apiname) - { - case "api_req_kousyou/destroyship": - { - for (int i = 0; i < Slot.Count; i++) - { - if (Slot[i] == -1) - continue; + switch (apiname) + { + case "api_req_kousyou/destroyship": + { + for (int i = 0; i < Slot.Count; i++) + { + if (Slot[i] == -1) + continue; - db.Equipments.Remove(Slot[i]); - } - } - break; + db.Equipments.Remove(Slot[i]); + } + } + break; - case "api_req_kaisou/open_exslot": - ExpansionSlot = -1; - break; - } - } + case "api_req_kaisou/open_exslot": + ExpansionSlot = -1; + break; + } + } - /// - /// 入渠完了時の処理を行います。 - /// - internal void Repair() - { + /// + /// 入渠完了時の処理を行います。 + /// + internal void Repair() + { - HPCurrent = HPMax; - Condition = Math.Max(Condition, 40); + HPCurrent = HPMax; + Condition = Math.Max(Condition, 40); - RawData.api_ndock_time = 0; - RawData.api_ndock_item[0] = 0; - RawData.api_ndock_item[1] = 0; + RawData.api_ndock_time = 0; + RawData.api_ndock_item[0] = 0; + RawData.api_ndock_item[1] = 0; - } + } - } + } } diff --git a/ElectronicObserver/Data/ShipDataMaster.cs b/ElectronicObserver/Data/ShipDataMaster.cs index 2ba0bbf43..fc1447d25 100644 --- a/ElectronicObserver/Data/ShipDataMaster.cs +++ b/ElectronicObserver/Data/ShipDataMaster.cs @@ -43,6 +43,11 @@ public class ShipDataMaster : ResponseWrapper, IIdentifiable /// public ShipTypes ShipType => (ShipTypes)(int)RawData.api_stype; + /// + /// 艦型 + /// + public int ShipClass => (int)RawData.api_ctype; + /// /// 改装Lv. @@ -93,6 +98,11 @@ public class ShipDataMaster : ResponseWrapper, IIdentifiable /// public int NeedCatapult { get; internal set; } + /// + /// 改装に戦闘詳報が必要かどうか + /// + public int NeedActionReport { get; internal set; } + #region Parameters diff --git a/ElectronicObserver/Observer/kcsapi/api_start2.cs b/ElectronicObserver/Observer/kcsapi/api_start2.cs index 61a2bf0d4..2b290db0a 100644 --- a/ElectronicObserver/Observer/kcsapi/api_start2.cs +++ b/ElectronicObserver/Observer/kcsapi/api_start2.cs @@ -214,6 +214,7 @@ public override void OnResponseReceived(dynamic data) { shipbefore.NeedBlueprint = (int)elem.api_drawing_count; shipbefore.NeedCatapult = (int)elem.api_catapult_count; + shipbefore.NeedActionReport = (int)elem.api_report_count; } } diff --git a/ElectronicObserver/Other/Information/apilist.txt b/ElectronicObserver/Other/Information/apilist.txt index c990a851a..7a80520c4 100644 --- a/ElectronicObserver/Other/Information/apilist.txt +++ b/ElectronicObserver/Other/Information/apilist.txt @@ -491,6 +491,7 @@ api_start2 :艦娘・装備固有データその他 api_upgrade_level :改装回数 api_drawing_count :要改装設計図 api_catapult_count :要試製甲板カタパルト + api_report_count :要戦闘詳報 api_sortno :? (概ね図鑑IDだが、霞(改/二/乙), 利根(改/二), 筑摩(改/二)などで異なる) api_mst_bgm :母港BGMデータ? diff --git a/ElectronicObserver/Other/Information/kcmemo.md b/ElectronicObserver/Other/Information/kcmemo.md index e977bb7ae..41b3477c9 100644 --- a/ElectronicObserver/Other/Information/kcmemo.md +++ b/ElectronicObserver/Other/Information/kcmemo.md @@ -5,9 +5,7 @@ 2000≦price<20000 とくに特別なフラグはない。 -また、ダイナミック家具割引が有効になる条件は、 -price≧100000 -値引き後は `int( ( price - 100000 ) * 0.1 )` になる。 +また、ダイナミック家具割引が有効になる条件は price≧100000 であり、値引き後は `int( ( price - 100000 ) * 0.1 )` になる。 #### ケッコンカッコカリ後の耐久値 ケッコン前の最大耐久値及び「最大耐久値の最大値」にのみ依存する。艦種や艦型、ケッコンのタイミングなどの影響は受けない。 @@ -64,12 +62,28 @@ value = min + ceil( ( max - min ) * ( 0.4 or 0.8 ) * Lv / 99 ) 2017/10/18 アップデートにより、衣替え艦娘がマスターから消滅した。 -以下に 2017/10/18 時点における ID と対応する艦娘及び衣装を示す。 +以下に 2017/12/30 時点における ID と対応する艦娘及び衣装を示す。 なお、ID: 787~799, 811~900 以外の名称については(参照できないため)公式のものではない。 |ID|艦名| |--:|:--| +|740|???| +|741|???| +|742|???| +|743|Xmas伊8| +|744|Xmas霰| +|745|Xmas衣笠| +|746|Xmas衣笠改二| +|747|Xmas佐渡| +|748|Xmas神威| +|749|Xmas長月| +|750|Xmas翔鶴| +|751|XmasLibeccio| +|752|Xmas狭霧| +|753|修羅場秋雲| +|754|???| +|755|???| |756|???| |757|スリガオ海峡突入満潮改二| |758|スリガオ海峡突入時雨改二| @@ -1112,6 +1126,7 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |530|伊504|対空機銃, 簡易輸送部材, 輸送機材|| |539|UIT-25|対空機銃, 簡易輸送部材, 輸送機材|特殊潜航艇| |541|長門改二|小口径主砲, 上陸用舟艇, 大口径主砲(II), 水上戦闘機, 特型内火艇|| +|543|長波改二|追加装甲(中型), 司令部施設|| |547|多摩改二|水上爆撃機, 上陸用舟艇, オートジャイロ, 追加装甲(中型), 航空要員, 水上戦闘機, 特型内火艇|| |605|Luigi Torelli改|簡易輸送部材, 輸送機材|特殊潜航艇| @@ -1220,8 +1235,8 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |854|季|戦果拡張任務!「Z作戦」前段作戦|2-4・6-1・6-3ボスA勝利各1/6-4ボスS勝利1 |861|季|強行輸送艦隊、抜錨!|1-6終点到達2|要(航空戦艦or補給艦)2 |862|季|前線の航空偵察を実施せよ!|6-3ボスA勝利2|要水母1軽巡2 -|873|季|北方海域警備を実施せよ!|3-1・3-2・3-3ボスA勝利各1|要軽巡1 -|???|?|北方海域戦闘哨戒を実施せよ!|3-5ボスS勝利2|要軽母1水母1軽巡1 +|873|季|北方海域警備を実施せよ!|3-1・3-2・3-3ボスA勝利各1|要軽巡1, 1エリア達成で50%,2エリアで80% +|875|季|精鋭「三一駆」、鉄底海域に突入せよ!|5-4ボスS勝利2|要長波改二/(高波改or沖波改or朝霜改) |303|日|「演習」で練度向上!|演習3 |304|日|「演習」で他提督を圧倒せよ!|演習勝利5 |302|週|大規模演習|演習勝利20 @@ -1246,6 +1261,7 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |674|日|工廠環境の整備|機銃廃棄3個,鋼材300保有|進捗は2/5から始まる(1個廃棄時点で50%,2個〃で80%達成になる) |613|週|資源の再利用|廃棄24回 |638|週|対空機銃量産|機銃廃棄6個 +|676|週|装備開発力の集中整備|(中口径主砲x3,副砲x3,簡易輸送部材x1)廃棄,鋼材2400保有|進捗は n/7 で1つごとに進む |626|月|精鋭「艦戦」隊の新編成|熟練搭乗員,零式艦戦21型>>装備の鳳翔旗艦,(零式艦戦21型x2,九六式艦戦x1)廃棄 |628|月|機種転換|零式艦戦21型(熟練)>>装備の空母旗艦,零式艦戦52型x2廃棄 |645|月|「洋上補給」物資の調達|三式弾廃棄,(燃料750,弾薬750,ドラム缶(輸送用)x2,九一式徹甲弾)保有 @@ -2032,8 +2048,27 @@ if( 対潜改修値 >= 9 ) { * 途中で撃沈された場合にどうなるかは未検証。 * 1戦闘あたり1隻ずつではあるが、複数艦退避することは可能。 * 退避した時点で HP は減少する。直後の `ship_deck` の時点で HP が減少したデータが送信されてくる。 - 減少量については未調査であるが、「山風改 Lv. 106 HP 6/35 → 1」「那智改二 Lv. 123 HP 14/63 → 4」「あきつ丸改 Lv. 51 HP 10/40 → 1」を確認している。 + ダメージについては [1, 現在HP) のランダムであると推測している。記録は以下の通り。 +``` +山風改 HP 6/35 → 1 +那智改二 HP 14/63 → 4 +あきつ丸改 HP 10/40 → 1 +時雨改二 HP 5/36 → 1 +山雲改 HP 4/31 → 2 +扶桑改二 HP 15/85 → 3 +朝雲改 HP 7/31 → 4 +満潮改二 HP 7/31 → 1 +山城改二 HP 12/85 → 11 +扶桑改二 HP 7/85 → 3 +時雨改二 HP 5/36 → 1 +山城改二 HP 11/85 → 1 +扶桑改二 HP 20/85 → 14 +山城改二 HP 7/85 → 6 +満潮改二 HP 4/31 → 3 +山城改二 HP 14/85 → 3 +山城改二 HP 19/85 → 11 +``` #### 索敵時の未帰還機について @@ -2046,5 +2081,20 @@ if( 対潜改修値 >= 9 ) { 全滅後に補給し 1-1 に出撃・戦闘・帰投後も同じレベルを維持していた。 +#### 特殊装備によるパラメータ補正 + +特定の艦が装備することで、通常以上にパラメータが向上する装備を以下に示す。 + +|対象装備ID|対象装備|対象艦ID|対象艦|特殊補正|補正込み上昇|重複可否|備考| +|--:|:--|--:|:--|:--|:--|:-:|:--| +|267|12.7cm連装砲D型改二|543|長波改二|火力+3, 回避+1|火力+6, 対空+3, 装甲+1, 回避+2, 命中+2|○| +|267|12.7cm連装砲D型改二|(22), (38)|島風型, 夕雲型|火力+2, 回避+1|火力+5, 対空+3, 装甲+1, 回避+2, 命中+2|○| +|267|12.7cm連装砲D型改二|(30)|陽炎型|火力+1, 回避+1|火力+4, 対空+3, 装甲+1, 回避+2, 命中+2|○| +|-|(水上電探)|229, 543|島風改, 長波改二|火力+1, 雷装+3, 回避+2|-|×|12.7cm連装砲D型改二 装備時のみ| +|268|北方迷彩(+北方装備)|216, 547, 217, 146|多摩改(二), 木曾改(二)|装甲+2, 回避+7|装甲+4, 回避+9|×| + +艦型指定のものは、未改造の艦にも適用される。 + + diff --git a/ElectronicObserver/Resource/ResourceManager.cs b/ElectronicObserver/Resource/ResourceManager.cs index 4f7926f2d..d6b9c024b 100644 --- a/ElectronicObserver/Resource/ResourceManager.cs +++ b/ElectronicObserver/Resource/ResourceManager.cs @@ -64,6 +64,7 @@ public enum IconContent ItemBlueprint, ItemCatapult, ItemPresentBox, + ItemActionReport, FormArsenal, FormBattle, FormCompass, @@ -293,8 +294,9 @@ private void LoadFromArchive(string path) LoadImageFromArchive(Icons, archive, mstpath + @"Item/Blueprint.png", "Item_Blueprint"); LoadImageFromArchive(Icons, archive, mstpath + @"Item/Catapult.png", "Item_Catapult"); LoadImageFromArchive(Icons, archive, mstpath + @"Item/PresentBox.png", "Item_PresentBox"); + LoadImageFromArchive(Icons, archive, mstpath + @"Item/ActionReport.png", "Item_ActionReport"); - LoadImageFromArchive(Icons, archive, mstpath + @"Form/Arsenal.png", "Form_Arsenal"); + LoadImageFromArchive(Icons, archive, mstpath + @"Form/Arsenal.png", "Form_Arsenal"); LoadImageFromArchive(Icons, archive, mstpath + @"Form/Battle.png", "Form_Battle"); LoadImageFromArchive(Icons, archive, mstpath + @"Form/Compass.png", "Form_Compass"); LoadImageFromArchive(Icons, archive, mstpath + @"Form/Dock.png", "Form_Dock"); diff --git a/ElectronicObserver/Utility/Data/Calculator.cs b/ElectronicObserver/Utility/Data/Calculator.cs index 181cc84e7..0e68fa63d 100644 --- a/ElectronicObserver/Utility/Data/Calculator.cs +++ b/ElectronicObserver/Utility/Data/Calculator.cs @@ -61,7 +61,8 @@ public static int GetParameterFromLevel(int min, int max, int lv) { EquipmentTypes.CarrierBasedFighter, 0.2 }, { EquipmentTypes.CarrierBasedBomber, 0.25 }, { EquipmentTypes.SeaplaneFighter, 0.2 }, - }; + { EquipmentTypes.Interceptor, 0.2 }, + }; diff --git a/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs b/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs index 144aa344a..5cc2fc902 100644 --- a/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs +++ b/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs @@ -18,1566 +18,1588 @@ namespace ElectronicObserver.Window.Dialog { - public partial class DialogAlbumMasterShip : Form - { - - private int _shipID; - - private ImageLabel[] Aircrafts; - private ImageLabel[] Equipments; - - private int loadingResourceShipID; - - - public DialogAlbumMasterShip() - { - InitializeComponent(); - - Aircrafts = new ImageLabel[] { Aircraft1, Aircraft2, Aircraft3, Aircraft4, Aircraft5 }; - Equipments = new ImageLabel[] { Equipment1, Equipment2, Equipment3, Equipment4, Equipment5 }; - - loadingResourceShipID = -1; - - TitleHP.ImageList = - TitleFirepower.ImageList = - TitleTorpedo.ImageList = - TitleAA.ImageList = - TitleArmor.ImageList = - TitleASW.ImageList = - TitleEvasion.ImageList = - TitleLOS.ImageList = - TitleLuck.ImageList = - TitleSpeed.ImageList = - TitleRange.ImageList = - Rarity.ImageList = - Fuel.ImageList = - Ammo.ImageList = - TitleBuildingTime.ImageList = - MaterialFuel.ImageList = - MaterialAmmo.ImageList = - MaterialSteel.ImageList = - MaterialBauxite.ImageList = - PowerUpFirepower.ImageList = - PowerUpTorpedo.ImageList = - PowerUpAA.ImageList = - PowerUpArmor.ImageList = - RemodelBeforeLevel.ImageList = - RemodelBeforeAmmo.ImageList = - RemodelBeforeSteel.ImageList = - RemodelAfterLevel.ImageList = - RemodelAfterAmmo.ImageList = - RemodelAfterSteel.ImageList = - ResourceManager.Instance.Icons; - - TitleAirSuperiority.ImageList = - TitleDayAttack.ImageList = - TitleNightAttack.ImageList = - Equipment1.ImageList = - Equipment2.ImageList = - Equipment3.ImageList = - Equipment4.ImageList = - Equipment5.ImageList = - ResourceManager.Instance.Equipments; - - TitleHP.ImageIndex = (int)ResourceManager.IconContent.ParameterHP; - TitleFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; - TitleTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; - TitleAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; - TitleArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; - TitleASW.ImageIndex = (int)ResourceManager.IconContent.ParameterASW; - TitleEvasion.ImageIndex = (int)ResourceManager.IconContent.ParameterEvasion; - TitleLOS.ImageIndex = (int)ResourceManager.IconContent.ParameterLOS; - TitleLuck.ImageIndex = (int)ResourceManager.IconContent.ParameterLuck; - TitleSpeed.ImageIndex = (int)ResourceManager.IconContent.ParameterSpeed; - TitleRange.ImageIndex = (int)ResourceManager.IconContent.ParameterRange; - Fuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; - Ammo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - TitleBuildingTime.ImageIndex = (int)ResourceManager.IconContent.FormArsenal; - MaterialFuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; - MaterialAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - MaterialSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; - MaterialBauxite.ImageIndex = (int)ResourceManager.IconContent.ResourceBauxite; - PowerUpFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; - PowerUpTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; - PowerUpAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; - PowerUpArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; - RemodelBeforeAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - RemodelBeforeSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; - RemodelAfterAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - RemodelAfterSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; - TitleAirSuperiority.ImageIndex = (int)ResourceManager.EquipmentContent.CarrierBasedFighter; - TitleDayAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Seaplane; - TitleNightAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Torpedo; + public partial class DialogAlbumMasterShip : Form + { + + private int _shipID; + + private ImageLabel[] Aircrafts; + private ImageLabel[] Equipments; + + private int loadingResourceShipID; + + + public DialogAlbumMasterShip() + { + InitializeComponent(); + + Aircrafts = new ImageLabel[] { Aircraft1, Aircraft2, Aircraft3, Aircraft4, Aircraft5 }; + Equipments = new ImageLabel[] { Equipment1, Equipment2, Equipment3, Equipment4, Equipment5 }; + + loadingResourceShipID = -1; + + TitleHP.ImageList = + TitleFirepower.ImageList = + TitleTorpedo.ImageList = + TitleAA.ImageList = + TitleArmor.ImageList = + TitleASW.ImageList = + TitleEvasion.ImageList = + TitleLOS.ImageList = + TitleLuck.ImageList = + TitleSpeed.ImageList = + TitleRange.ImageList = + Rarity.ImageList = + Fuel.ImageList = + Ammo.ImageList = + TitleBuildingTime.ImageList = + MaterialFuel.ImageList = + MaterialAmmo.ImageList = + MaterialSteel.ImageList = + MaterialBauxite.ImageList = + PowerUpFirepower.ImageList = + PowerUpTorpedo.ImageList = + PowerUpAA.ImageList = + PowerUpArmor.ImageList = + RemodelBeforeLevel.ImageList = + RemodelBeforeAmmo.ImageList = + RemodelBeforeSteel.ImageList = + RemodelAfterLevel.ImageList = + RemodelAfterAmmo.ImageList = + RemodelAfterSteel.ImageList = + ResourceManager.Instance.Icons; + + TitleAirSuperiority.ImageList = + TitleDayAttack.ImageList = + TitleNightAttack.ImageList = + Equipment1.ImageList = + Equipment2.ImageList = + Equipment3.ImageList = + Equipment4.ImageList = + Equipment5.ImageList = + ResourceManager.Instance.Equipments; + + TitleHP.ImageIndex = (int)ResourceManager.IconContent.ParameterHP; + TitleFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; + TitleTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; + TitleAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; + TitleArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; + TitleASW.ImageIndex = (int)ResourceManager.IconContent.ParameterASW; + TitleEvasion.ImageIndex = (int)ResourceManager.IconContent.ParameterEvasion; + TitleLOS.ImageIndex = (int)ResourceManager.IconContent.ParameterLOS; + TitleLuck.ImageIndex = (int)ResourceManager.IconContent.ParameterLuck; + TitleSpeed.ImageIndex = (int)ResourceManager.IconContent.ParameterSpeed; + TitleRange.ImageIndex = (int)ResourceManager.IconContent.ParameterRange; + Fuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; + Ammo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + TitleBuildingTime.ImageIndex = (int)ResourceManager.IconContent.FormArsenal; + MaterialFuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; + MaterialAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + MaterialSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; + MaterialBauxite.ImageIndex = (int)ResourceManager.IconContent.ResourceBauxite; + PowerUpFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; + PowerUpTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; + PowerUpAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; + PowerUpArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; + RemodelBeforeAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + RemodelBeforeSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; + RemodelAfterAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + RemodelAfterSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; + TitleAirSuperiority.ImageIndex = (int)ResourceManager.EquipmentContent.CarrierBasedFighter; + TitleDayAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Seaplane; + TitleNightAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Torpedo; - ParameterLevel.Value = ParameterLevel.Maximum = ExpTable.ShipMaximumLevel; - - - TableBattle.Visible = false; - BasePanelShipGirl.Visible = false; - - - ControlHelper.SetDoubleBuffered(TableShipName); - ControlHelper.SetDoubleBuffered(TableParameterMain); - ControlHelper.SetDoubleBuffered(TableParameterSub); - ControlHelper.SetDoubleBuffered(TableConsumption); - ControlHelper.SetDoubleBuffered(TableEquipment); - ControlHelper.SetDoubleBuffered(TableArsenal); - ControlHelper.SetDoubleBuffered(TableRemodel); - ControlHelper.SetDoubleBuffered(TableBattle); - - ControlHelper.SetDoubleBuffered(ShipView); - - - //ShipView Initialize - ShipView.SuspendLayout(); - - ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; - ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; - - - ShipView.Rows.Clear(); - - List rows = new List(KCDatabase.Instance.MasterShips.Values.Count(s => s.Name != "なし")); - - foreach (var ship in KCDatabase.Instance.MasterShips.Values) - { - - if (ship.Name == "なし") continue; - - DataGridViewRow row = new DataGridViewRow(); - row.CreateCells(ShipView); - row.SetValues(ship.ShipID, ship.ShipTypeName, ship.NameWithClass); - row.Cells[ShipView_ShipType.Index].Tag = ship.ShipType; - row.Cells[ShipView_Name.Index].Tag = ship.IsAbyssalShip ? null : ship.NameReading; - rows.Add(row); - - } - ShipView.Rows.AddRange(rows.ToArray()); + ParameterLevel.Value = ParameterLevel.Maximum = ExpTable.ShipMaximumLevel; + + + TableBattle.Visible = false; + BasePanelShipGirl.Visible = false; + + + ControlHelper.SetDoubleBuffered(TableShipName); + ControlHelper.SetDoubleBuffered(TableParameterMain); + ControlHelper.SetDoubleBuffered(TableParameterSub); + ControlHelper.SetDoubleBuffered(TableConsumption); + ControlHelper.SetDoubleBuffered(TableEquipment); + ControlHelper.SetDoubleBuffered(TableArsenal); + ControlHelper.SetDoubleBuffered(TableRemodel); + ControlHelper.SetDoubleBuffered(TableBattle); + + ControlHelper.SetDoubleBuffered(ShipView); + + + //ShipView Initialize + ShipView.SuspendLayout(); + + ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; + ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; + + + ShipView.Rows.Clear(); + + List rows = new List(KCDatabase.Instance.MasterShips.Values.Count(s => s.Name != "なし")); + + foreach (var ship in KCDatabase.Instance.MasterShips.Values) + { + + if (ship.Name == "なし") continue; + + DataGridViewRow row = new DataGridViewRow(); + row.CreateCells(ShipView); + row.SetValues(ship.ShipID, ship.ShipTypeName, ship.NameWithClass); + row.Cells[ShipView_ShipType.Index].Tag = ship.ShipType; + row.Cells[ShipView_Name.Index].Tag = ship.IsAbyssalShip ? null : ship.NameReading; + rows.Add(row); + + } + ShipView.Rows.AddRange(rows.ToArray()); - ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; - ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; + ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; + ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; - ShipView.Sort(ShipView_ShipID, ListSortDirection.Ascending); - ShipView.ResumeLayout(); - } + ShipView.Sort(ShipView_ShipID, ListSortDirection.Ascending); + ShipView.ResumeLayout(); + } - public DialogAlbumMasterShip(int shipID) - : this() - { + public DialogAlbumMasterShip(int shipID) + : this() + { - UpdateAlbumPage(shipID); + UpdateAlbumPage(shipID); - if (KCDatabase.Instance.MasterShips.ContainsKey(shipID)) - { - var row = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == shipID); - if (row != null) - ShipView.FirstDisplayedScrollingRowIndex = row.Index; - } + if (KCDatabase.Instance.MasterShips.ContainsKey(shipID)) + { + var row = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == shipID); + if (row != null) + ShipView.FirstDisplayedScrollingRowIndex = row.Index; + } - } + } - private void DialogAlbumMasterShip_Load(object sender, EventArgs e) - { + private void DialogAlbumMasterShip_Load(object sender, EventArgs e) + { - this.Icon = ResourceManager.ImageToIcon(ResourceManager.Instance.Icons.Images[(int)ResourceManager.IconContent.FormAlbumShip]); + this.Icon = ResourceManager.ImageToIcon(ResourceManager.Instance.Icons.Images[(int)ResourceManager.IconContent.FormAlbumShip]); - } + } - private void ShipView_SortCompare(object sender, DataGridViewSortCompareEventArgs e) - { + private void ShipView_SortCompare(object sender, DataGridViewSortCompareEventArgs e) + { - if (e.Column.Index == ShipView_ShipType.Index) - { - e.SortResult = (int)ShipView[e.Column.Index, e.RowIndex1].Tag - (int)ShipView[e.Column.Index, e.RowIndex2].Tag; + if (e.Column.Index == ShipView_ShipType.Index) + { + e.SortResult = (int)ShipView[e.Column.Index, e.RowIndex1].Tag - (int)ShipView[e.Column.Index, e.RowIndex2].Tag; - } - else if (e.Column.Index == ShipView_Name.Index) - { + } + else if (e.Column.Index == ShipView_Name.Index) + { - // 艦娘優先; 艦娘同士なら読みで比べる、深海棲艦同士なら名前で比べる + // 艦娘優先; 艦娘同士なら読みで比べる、深海棲艦同士なら名前で比べる - string tag1 = ShipView[e.Column.Index, e.RowIndex1].Tag as string; - string tag2 = ShipView[e.Column.Index, e.RowIndex2].Tag as string; + string tag1 = ShipView[e.Column.Index, e.RowIndex1].Tag as string; + string tag2 = ShipView[e.Column.Index, e.RowIndex2].Tag as string; - if (tag1 != null) - { - if (tag2 != null) - e.SortResult = tag1.CompareTo(tag2); - else - e.SortResult = -1; - } - else - { - if (tag2 != null) - e.SortResult = 1; - else - e.SortResult = 0; - } + if (tag1 != null) + { + if (tag2 != null) + e.SortResult = tag1.CompareTo(tag2); + else + e.SortResult = -1; + } + else + { + if (tag2 != null) + e.SortResult = 1; + else + e.SortResult = 0; + } - if (e.SortResult == 0) - e.SortResult = ((string)e.CellValue1).CompareTo(e.CellValue2); + if (e.SortResult == 0) + e.SortResult = ((string)e.CellValue1).CompareTo(e.CellValue2); - } - else - { - e.SortResult = ((IComparable)e.CellValue1).CompareTo(e.CellValue2); - } + } + else + { + e.SortResult = ((IComparable)e.CellValue1).CompareTo(e.CellValue2); + } - if (e.SortResult == 0) - { - e.SortResult = (int)(ShipView.Rows[e.RowIndex1].Tag ?? 0) - (int)(ShipView.Rows[e.RowIndex2].Tag ?? 0); - } + if (e.SortResult == 0) + { + e.SortResult = (int)(ShipView.Rows[e.RowIndex1].Tag ?? 0) - (int)(ShipView.Rows[e.RowIndex2].Tag ?? 0); + } - e.Handled = true; - } + e.Handled = true; + } - private void ShipView_Sorted(object sender, EventArgs e) - { + private void ShipView_Sorted(object sender, EventArgs e) + { - for (int i = 0; i < ShipView.Rows.Count; i++) - { - ShipView.Rows[i].Tag = i; - } + for (int i = 0; i < ShipView.Rows.Count; i++) + { + ShipView.Rows[i].Tag = i; + } - } + } - private void ShipView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) - { + private void ShipView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) + { - if (e.RowIndex >= 0) - { - int shipID = (int)ShipView.Rows[e.RowIndex].Cells[0].Value; + if (e.RowIndex >= 0) + { + int shipID = (int)ShipView.Rows[e.RowIndex].Cells[0].Value; - if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) - { - Cursor = Cursors.AppStarting; - new DialogAlbumMasterShip(shipID).Show(Owner); - Cursor = Cursors.Default; + if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) + { + Cursor = Cursors.AppStarting; + new DialogAlbumMasterShip(shipID).Show(Owner); + Cursor = Cursors.Default; - } - else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) - { - UpdateAlbumPage(shipID); - } - } + } + else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) + { + UpdateAlbumPage(shipID); + } + } - } + } - private void UpdateAlbumPage(int shipID) - { + private void UpdateAlbumPage(int shipID) + { - KCDatabase db = KCDatabase.Instance; - ShipDataMaster ship = db.MasterShips[shipID]; + KCDatabase db = KCDatabase.Instance; + ShipDataMaster ship = db.MasterShips[shipID]; - if (ship == null) return; + if (ship == null) return; - BasePanelShipGirl.SuspendLayout(); + BasePanelShipGirl.SuspendLayout(); - //header - TableShipName.SuspendLayout(); - _shipID = shipID; - ShipID.Text = ship.ShipID.ToString(); - AlbumNo.Text = ship.AlbumNo.ToString(); + //header + TableShipName.SuspendLayout(); + _shipID = shipID; + ShipID.Text = ship.ShipID.ToString(); + AlbumNo.Text = ship.AlbumNo.ToString(); - ResourceName.Text = $"{ship.ResourceName} {ship.ResourceGraphicVersion}/{ship.ResourceVoiceVersion}/{ship.ResourcePortVoiceVersion}"; - ToolTipInfo.SetToolTip(ResourceName, string.Format("リソース名: {0}\r\nグラフィック ver. {1}\r\nボイス ver. {2}\r\n母港ボイス ver. {3}\r\n({4})", - ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, Constants.GetVoiceFlag(ship.VoiceFlag))); + ResourceName.Text = $"{ship.ResourceName} {ship.ResourceGraphicVersion}/{ship.ResourceVoiceVersion}/{ship.ResourcePortVoiceVersion}"; + ToolTipInfo.SetToolTip(ResourceName, string.Format("リソース名: {0}\r\nグラフィック ver. {1}\r\nボイス ver. {2}\r\n母港ボイス ver. {3}\r\n({4})", + ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, Constants.GetVoiceFlag(ship.VoiceFlag))); - ShipType.Text = ship.IsLandBase ? "陸上施設" : ship.ShipTypeName; - ShipName.Text = ship.NameWithClass; - ShipName.ForeColor = ship.GetShipNameColor(); - ToolTipInfo.SetToolTip(ShipName, (!ship.IsAbyssalShip ? ship.NameReading + "\r\n" : "") + "(右クリックでコピー)"); - TableShipName.ResumeLayout(); + ShipType.Text = ship.IsLandBase ? "陸上施設" : ship.ShipTypeName; + ToolTipInfo.SetToolTip(ShipType, Constants.GetShipClass(ship.ShipClass)); + ShipName.Text = ship.NameWithClass; + ShipName.ForeColor = ship.GetShipNameColor(); + ToolTipInfo.SetToolTip(ShipName, (!ship.IsAbyssalShip ? ship.NameReading + "\r\n" : "") + "(右クリックでコピー)"); + TableShipName.ResumeLayout(); - //main parameter - TableParameterMain.SuspendLayout(); + //main parameter + TableParameterMain.SuspendLayout(); - if (!ship.IsAbyssalShip) - { + if (!ship.IsAbyssalShip) + { - TitleParameterMin.Text = "初期値"; - TitleParameterMax.Text = "最大値"; + TitleParameterMin.Text = "初期値"; + TitleParameterMax.Text = "最大値"; - HPMin.Text = ship.HPMin.ToString(); - HPMax.Text = ship.HPMaxMarried.ToString(); - ToolTipInfo.SetToolTip(HPMin, string.Format("改修後: {0} (+{1})", ship.HPMaxModernized, ship.HPMaxModernizable)); - ToolTipInfo.SetToolTip(HPMax, string.Format("改修後: {0} (+{1})\r\n(内部最大耐久: {2})", ship.HPMaxMarriedModernized, ship.HPMaxMarriedModernizable, ship.HPMax)); + HPMin.Text = ship.HPMin.ToString(); + HPMax.Text = ship.HPMaxMarried.ToString(); + ToolTipInfo.SetToolTip(HPMin, string.Format("改修後: {0} (+{1})", ship.HPMaxModernized, ship.HPMaxModernizable)); + ToolTipInfo.SetToolTip(HPMax, string.Format("改修後: {0} (+{1})\r\n(内部最大耐久: {2})", ship.HPMaxMarriedModernized, ship.HPMaxMarriedModernizable, ship.HPMax)); - FirepowerMin.Text = ship.FirepowerMin.ToString(); - FirepowerMax.Text = ship.FirepowerMax.ToString(); + FirepowerMin.Text = ship.FirepowerMin.ToString(); + FirepowerMax.Text = ship.FirepowerMax.ToString(); - TorpedoMin.Text = ship.TorpedoMin.ToString(); - TorpedoMax.Text = ship.TorpedoMax.ToString(); + TorpedoMin.Text = ship.TorpedoMin.ToString(); + TorpedoMax.Text = ship.TorpedoMax.ToString(); - AAMin.Text = ship.AAMin.ToString(); - AAMax.Text = ship.AAMax.ToString(); + AAMin.Text = ship.AAMin.ToString(); + AAMax.Text = ship.AAMax.ToString(); - ArmorMin.Text = ship.ArmorMin.ToString(); - ArmorMax.Text = ship.ArmorMax.ToString(); + ArmorMin.Text = ship.ArmorMin.ToString(); + ArmorMax.Text = ship.ArmorMax.ToString(); - ASWMin.Text = GetParameterMinBound(ship.ASW); - ASWMax.Text = GetParameterMax(ship.ASW); + ASWMin.Text = GetParameterMinBound(ship.ASW); + ASWMax.Text = GetParameterMax(ship.ASW); - EvasionMin.Text = GetParameterMinBound(ship.Evasion); - EvasionMax.Text = GetParameterMax(ship.Evasion); + EvasionMin.Text = GetParameterMinBound(ship.Evasion); + EvasionMax.Text = GetParameterMax(ship.Evasion); - LOSMin.Text = GetParameterMinBound(ship.LOS); - LOSMax.Text = GetParameterMax(ship.LOS); + LOSMin.Text = GetParameterMinBound(ship.LOS); + LOSMax.Text = GetParameterMax(ship.LOS); - LuckMin.Text = ship.LuckMin.ToString(); - LuckMax.Text = ship.LuckMax.ToString(); + LuckMin.Text = ship.LuckMin.ToString(); + LuckMax.Text = ship.LuckMax.ToString(); - } - else - { + } + else + { - int hp = ship.HPMin; - int firepower = ship.FirepowerMax; - int torpedo = ship.TorpedoMax; - int aa = ship.AAMax; - int armor = ship.ArmorMax; - int asw = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum : 0; - int evasion = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum : 0; - int los = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum : 0; - int luck = ship.LuckMax; + int hp = ship.HPMin; + int firepower = ship.FirepowerMax; + int torpedo = ship.TorpedoMax; + int aa = ship.AAMax; + int armor = ship.ArmorMax; + int asw = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum : 0; + int evasion = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum : 0; + int los = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum : 0; + int luck = ship.LuckMax; - if (ship.DefaultSlot != null) - { - int count = ship.DefaultSlot.Count; - for (int i = 0; i < count; i++) - { - EquipmentDataMaster eq = KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[i]]; - if (eq == null) continue; + if (ship.DefaultSlot != null) + { + int count = ship.DefaultSlot.Count; + for (int i = 0; i < count; i++) + { + EquipmentDataMaster eq = KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[i]]; + if (eq == null) continue; - firepower += eq.Firepower; - torpedo += eq.Torpedo; - aa += eq.AA; - armor += eq.Armor; - asw += eq.ASW; - evasion += eq.Evasion; - los += eq.LOS; - luck += eq.Luck; - } - } + firepower += eq.Firepower; + torpedo += eq.Torpedo; + aa += eq.AA; + armor += eq.Armor; + asw += eq.ASW; + evasion += eq.Evasion; + los += eq.LOS; + luck += eq.Luck; + } + } - TitleParameterMin.Text = "基本値"; - TitleParameterMax.Text = "装備込"; + TitleParameterMin.Text = "基本値"; + TitleParameterMax.Text = "装備込"; - HPMin.Text = ship.HPMin > 0 ? ship.HPMin.ToString() : "???"; - HPMax.Text = hp > 0 ? hp.ToString() : "???"; - ToolTipInfo.SetToolTip(HPMin, null); - ToolTipInfo.SetToolTip(HPMax, null); + HPMin.Text = ship.HPMin > 0 ? ship.HPMin.ToString() : "???"; + HPMax.Text = hp > 0 ? hp.ToString() : "???"; + ToolTipInfo.SetToolTip(HPMin, null); + ToolTipInfo.SetToolTip(HPMax, null); - FirepowerMin.Text = ship.FirepowerMax.ToString(); - FirepowerMax.Text = firepower.ToString(); + FirepowerMin.Text = ship.FirepowerMax.ToString(); + FirepowerMax.Text = firepower.ToString(); - TorpedoMin.Text = ship.TorpedoMax.ToString(); - TorpedoMax.Text = torpedo.ToString(); - - AAMin.Text = ship.AAMax.ToString(); - AAMax.Text = aa.ToString(); - - ArmorMin.Text = ship.ArmorMax.ToString(); - ArmorMax.Text = armor.ToString(); - - ASWMin.Text = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum.ToString() : "???"; - ASWMax.Text = asw.ToString(); - - EvasionMin.Text = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum.ToString() : "???"; - EvasionMax.Text = evasion.ToString(); - - LOSMin.Text = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum.ToString() : "???"; - LOSMax.Text = los.ToString(); - - LuckMin.Text = ship.LuckMax > 0 ? ship.LuckMax.ToString() : "???"; - LuckMax.Text = luck > 0 ? luck.ToString() : "???"; - - } - UpdateLevelParameter(ship.ShipID); - - TableParameterMain.ResumeLayout(); - - - //sub parameter - TableParameterSub.SuspendLayout(); - - Speed.Text = Constants.GetSpeed(ship.Speed); - if (!ship.IsAbyssalShip) - { - Range.Text = Constants.GetRange(ship.Range); - ToolTipInfo.SetToolTip(Range, null); - } - else - { - var availableEquipments = (ship.DefaultSlot ?? Enumerable.Repeat(-1, 5)) - .Select(id => KCDatabase.Instance.MasterEquipments[id]) - .Where(eq => eq != null); - Range.Text = Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0)); - ToolTipInfo.SetToolTip(Range, "素の射程: " + Constants.GetRange(ship.Range)); - } - Rarity.Text = Constants.GetShipRarity(ship.Rarity); - Rarity.ImageIndex = (int)ResourceManager.IconContent.RarityRed + ship.Rarity; - - TableParameterSub.ResumeLayout(); - - TableConsumption.SuspendLayout(); - - Fuel.Text = ship.Fuel.ToString(); - Ammo.Text = ship.Ammo.ToString(); - - string tooltiptext = string.Format( - "入渠時の消費:\r\nHP1あたり: 鋼 {0:F2} / 燃 {1:F2}\r\n最大: 鋼 {2} / 燃 {3}\r\n", - (ship.Fuel * 0.06), - (ship.Fuel * 0.032), - (int)(ship.Fuel * 0.06 * (ship.HPMaxMarried - 1)), - (int)(ship.Fuel * 0.032 * (ship.HPMaxMarried - 1)) - ); - - ToolTipInfo.SetToolTip(TableConsumption, tooltiptext); - ToolTipInfo.SetToolTip(TitleConsumption, tooltiptext); - ToolTipInfo.SetToolTip(Fuel, tooltiptext); - ToolTipInfo.SetToolTip(Ammo, tooltiptext); - - TableConsumption.ResumeLayout(); - - Description.Text = ship.MessageAlbum != "" ? ship.MessageAlbum : ship.MessageGet; - Description.Tag = ship.MessageAlbum != "" ? 1 : 0; - - - //equipment - TableEquipment.SuspendLayout(); - - for (int i = 0; i < Equipments.Length; i++) - { - - if (ship.Aircraft[i] > 0 || i < ship.SlotSize) - Aircrafts[i].Text = ship.Aircraft[i].ToString(); - else - Aircrafts[i].Text = ""; - - - ToolTipInfo.SetToolTip(Equipments[i], null); - - if (ship.DefaultSlot == null) - { - if (i < ship.SlotSize) - { - Equipments[i].Text = "???"; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Unknown; - } - else - { - Equipments[i].Text = ""; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; - } - - } - else if (ship.DefaultSlot[i] != -1) - { - EquipmentDataMaster eq = db.MasterEquipments[ship.DefaultSlot[i]]; - if (eq == null) - { - // 破損データが入っていた場合 - Equipments[i].Text = "(なし)"; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; - - } - else - { - - Equipments[i].Text = eq.Name; - - int eqicon = eq.EquipmentType[3]; - if (eqicon >= (int)ResourceManager.EquipmentContent.Locked) - eqicon = (int)ResourceManager.EquipmentContent.Unknown; - - Equipments[i].ImageIndex = eqicon; - - { - StringBuilder sb = new StringBuilder(); - - sb.AppendFormat("{0} {1} (ID: {2})\r\n", eq.CategoryTypeInstance.Name, eq.Name, eq.EquipmentID); - if (eq.Firepower != 0) sb.AppendFormat("火力 {0:+0;-0}\r\n", eq.Firepower); - if (eq.Torpedo != 0) sb.AppendFormat("雷装 {0:+0;-0}\r\n", eq.Torpedo); - if (eq.AA != 0) sb.AppendFormat("対空 {0:+0;-0}\r\n", eq.AA); - if (eq.Armor != 0) sb.AppendFormat("装甲 {0:+0;-0}\r\n", eq.Armor); - if (eq.ASW != 0) sb.AppendFormat("対潜 {0:+0;-0}\r\n", eq.ASW); - if (eq.Evasion != 0) sb.AppendFormat("回避 {0:+0;-0}\r\n", eq.Evasion); - if (eq.LOS != 0) sb.AppendFormat("索敵 {0:+0;-0}\r\n", eq.LOS); - if (eq.Accuracy != 0) sb.AppendFormat("命中 {0:+0;-0}\r\n", eq.Accuracy); - if (eq.Bomber != 0) sb.AppendFormat("爆装 {0:+0;-0}\r\n", eq.Bomber); - sb.AppendLine("(右クリックで図鑑)"); - - ToolTipInfo.SetToolTip(Equipments[i], sb.ToString()); - } - } - - } - else if (i < ship.SlotSize) - { - Equipments[i].Text = "(なし)"; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; - - } - else - { - Equipments[i].Text = ""; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; - } - } - - TableEquipment.ResumeLayout(); - - - //arsenal - TableArsenal.SuspendLayout(); - BuildingTime.Text = DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)); - - MaterialFuel.Text = ship.Material[0].ToString(); - MaterialAmmo.Text = ship.Material[1].ToString(); - MaterialSteel.Text = ship.Material[2].ToString(); - MaterialBauxite.Text = ship.Material[3].ToString(); - - PowerUpFirepower.Text = ship.PowerUp[0].ToString(); - PowerUpTorpedo.Text = ship.PowerUp[1].ToString(); - PowerUpAA.Text = ship.PowerUp[2].ToString(); - PowerUpArmor.Text = ship.PowerUp[3].ToString(); - - TableArsenal.ResumeLayout(); - - - //remodel - if (!ship.IsAbyssalShip) - { - - TableRemodel.SuspendLayout(); - - if (ship.RemodelBeforeShipID == 0) - { - RemodelBeforeShipName.Text = "(なし)"; - ToolTipInfo.SetToolTip(RemodelBeforeShipName, null); - RemodelBeforeLevel.Text = ""; - RemodelBeforeLevel.ImageIndex = -1; - ToolTipInfo.SetToolTip(RemodelBeforeLevel, null); - RemodelBeforeAmmo.Text = "-"; - RemodelBeforeSteel.Text = "-"; - } - else - { - ShipDataMaster sbefore = ship.RemodelBeforeShip; - RemodelBeforeShipName.Text = sbefore.Name; - ToolTipInfo.SetToolTip(RemodelBeforeShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); - RemodelBeforeLevel.Text = string.Format("Lv. {0}", sbefore.RemodelAfterLevel); - RemodelBeforeLevel.ImageIndex = sbefore.NeedCatapult > 0 ? (int)ResourceManager.IconContent.ItemCatapult : sbefore.NeedBlueprint > 0 ? (int)ResourceManager.IconContent.ItemBlueprint : -1; - ToolTipInfo.SetToolTip(RemodelBeforeLevel, GetRemodelItem(sbefore)); - RemodelBeforeAmmo.Text = sbefore.RemodelAmmo.ToString(); - RemodelBeforeSteel.Text = sbefore.RemodelSteel.ToString(); - } - - if (ship.RemodelAfterShipID == 0) - { - RemodelAfterShipName.Text = "(なし)"; - ToolTipInfo.SetToolTip(RemodelAfterShipName, null); - RemodelAfterLevel.Text = ""; - RemodelAfterLevel.ImageIndex = -1; - ToolTipInfo.SetToolTip(RemodelAfterLevel, null); - RemodelAfterAmmo.Text = "-"; - RemodelAfterSteel.Text = "-"; - } - else - { - RemodelAfterShipName.Text = ship.RemodelAfterShip.Name; - ToolTipInfo.SetToolTip(RemodelAfterShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); - RemodelAfterLevel.Text = string.Format("Lv. {0}", ship.RemodelAfterLevel); - RemodelAfterLevel.ImageIndex = ship.NeedCatapult > 0 ? (int)ResourceManager.IconContent.ItemCatapult : ship.NeedBlueprint > 0 ? (int)ResourceManager.IconContent.ItemBlueprint : -1; - ToolTipInfo.SetToolTip(RemodelAfterLevel, GetRemodelItem(ship)); - RemodelAfterAmmo.Text = ship.RemodelAmmo.ToString(); - RemodelAfterSteel.Text = ship.RemodelSteel.ToString(); - } - TableRemodel.ResumeLayout(); - - - TableRemodel.Visible = true; - TableBattle.Visible = false; - - - } - else - { - - TableBattle.SuspendLayout(); - - AirSuperiority.Text = Calculator.GetAirSuperiority(ship).ToString(); - DayAttack.Text = Constants.GetDayAttackKind(Calculator.GetDayAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); - NightAttack.Text = Constants.GetNightAttackKind(Calculator.GetNightAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); - - TableBattle.ResumeLayout(); - - TableRemodel.Visible = false; - TableBattle.Visible = true; - - } - - - if (ShipBanner.Image != null) - { - var img = ShipBanner.Image; - ShipBanner.Image = null; - img.Dispose(); - } - if (!ImageLoader.IsBusy) - { - loadingResourceShipID = ship.ShipID; - ImageLoader.RunWorkerAsync(ship.ResourceName); - } - - - - BasePanelShipGirl.ResumeLayout(); - BasePanelShipGirl.Visible = true; - - - this.Text = "艦船図鑑 - " + ship.NameWithClass; - - } - - - private void UpdateLevelParameter(int shipID) - { - - ShipDataMaster ship = KCDatabase.Instance.MasterShips[shipID]; - - if (ship == null) - return; - - if (!ship.IsAbyssalShip) - { - ASWLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.ASW); - EvasionLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.Evasion); - LOSLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.LOS); - ASWLevel.Visible = - ASWSeparater.Visible = - EvasionLevel.Visible = - EvasionSeparater.Visible = - LOSLevel.Visible = - LOSSeparater.Visible = true; - - } - else - { - ASWLevel.Visible = - ASWSeparater.Visible = - EvasionLevel.Visible = - EvasionSeparater.Visible = - LOSLevel.Visible = - LOSSeparater.Visible = false; - } - } + TorpedoMin.Text = ship.TorpedoMax.ToString(); + TorpedoMax.Text = torpedo.ToString(); + + AAMin.Text = ship.AAMax.ToString(); + AAMax.Text = aa.ToString(); + + ArmorMin.Text = ship.ArmorMax.ToString(); + ArmorMax.Text = armor.ToString(); + + ASWMin.Text = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum.ToString() : "???"; + ASWMax.Text = asw.ToString(); + + EvasionMin.Text = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum.ToString() : "???"; + EvasionMax.Text = evasion.ToString(); + + LOSMin.Text = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum.ToString() : "???"; + LOSMax.Text = los.ToString(); + + LuckMin.Text = ship.LuckMax > 0 ? ship.LuckMax.ToString() : "???"; + LuckMax.Text = luck > 0 ? luck.ToString() : "???"; + + } + UpdateLevelParameter(ship.ShipID); + + TableParameterMain.ResumeLayout(); + + + //sub parameter + TableParameterSub.SuspendLayout(); + + Speed.Text = Constants.GetSpeed(ship.Speed); + if (!ship.IsAbyssalShip) + { + Range.Text = Constants.GetRange(ship.Range); + ToolTipInfo.SetToolTip(Range, null); + } + else + { + var availableEquipments = (ship.DefaultSlot ?? Enumerable.Repeat(-1, 5)) + .Select(id => KCDatabase.Instance.MasterEquipments[id]) + .Where(eq => eq != null); + Range.Text = Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0)); + ToolTipInfo.SetToolTip(Range, "素の射程: " + Constants.GetRange(ship.Range)); + } + Rarity.Text = Constants.GetShipRarity(ship.Rarity); + Rarity.ImageIndex = (int)ResourceManager.IconContent.RarityRed + ship.Rarity; + + TableParameterSub.ResumeLayout(); + + TableConsumption.SuspendLayout(); + + Fuel.Text = ship.Fuel.ToString(); + Ammo.Text = ship.Ammo.ToString(); + + string tooltiptext = string.Format( + "入渠時の消費:\r\nHP1あたり: 鋼 {0:F2} / 燃 {1:F2}\r\n最大: 鋼 {2} / 燃 {3}\r\n", + (ship.Fuel * 0.06), + (ship.Fuel * 0.032), + (int)(ship.Fuel * 0.06 * (ship.HPMaxMarried - 1)), + (int)(ship.Fuel * 0.032 * (ship.HPMaxMarried - 1)) + ); + + ToolTipInfo.SetToolTip(TableConsumption, tooltiptext); + ToolTipInfo.SetToolTip(TitleConsumption, tooltiptext); + ToolTipInfo.SetToolTip(Fuel, tooltiptext); + ToolTipInfo.SetToolTip(Ammo, tooltiptext); + + TableConsumption.ResumeLayout(); + + Description.Text = ship.MessageAlbum != "" ? ship.MessageAlbum : ship.MessageGet; + Description.Tag = ship.MessageAlbum != "" ? 1 : 0; + + + //equipment + TableEquipment.SuspendLayout(); + + for (int i = 0; i < Equipments.Length; i++) + { + + if (ship.Aircraft[i] > 0 || i < ship.SlotSize) + Aircrafts[i].Text = ship.Aircraft[i].ToString(); + else + Aircrafts[i].Text = ""; + + + ToolTipInfo.SetToolTip(Equipments[i], null); + + if (ship.DefaultSlot == null) + { + if (i < ship.SlotSize) + { + Equipments[i].Text = "???"; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Unknown; + } + else + { + Equipments[i].Text = ""; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; + } + + } + else if (ship.DefaultSlot[i] != -1) + { + EquipmentDataMaster eq = db.MasterEquipments[ship.DefaultSlot[i]]; + if (eq == null) + { + // 破損データが入っていた場合 + Equipments[i].Text = "(なし)"; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; + + } + else + { + + Equipments[i].Text = eq.Name; + + int eqicon = eq.EquipmentType[3]; + if (eqicon >= (int)ResourceManager.EquipmentContent.Locked) + eqicon = (int)ResourceManager.EquipmentContent.Unknown; + + Equipments[i].ImageIndex = eqicon; + + { + StringBuilder sb = new StringBuilder(); + + sb.AppendFormat("{0} {1} (ID: {2})\r\n", eq.CategoryTypeInstance.Name, eq.Name, eq.EquipmentID); + if (eq.Firepower != 0) sb.AppendFormat("火力 {0:+0;-0}\r\n", eq.Firepower); + if (eq.Torpedo != 0) sb.AppendFormat("雷装 {0:+0;-0}\r\n", eq.Torpedo); + if (eq.AA != 0) sb.AppendFormat("対空 {0:+0;-0}\r\n", eq.AA); + if (eq.Armor != 0) sb.AppendFormat("装甲 {0:+0;-0}\r\n", eq.Armor); + if (eq.ASW != 0) sb.AppendFormat("対潜 {0:+0;-0}\r\n", eq.ASW); + if (eq.Evasion != 0) sb.AppendFormat("回避 {0:+0;-0}\r\n", eq.Evasion); + if (eq.LOS != 0) sb.AppendFormat("索敵 {0:+0;-0}\r\n", eq.LOS); + if (eq.Accuracy != 0) sb.AppendFormat("命中 {0:+0;-0}\r\n", eq.Accuracy); + if (eq.Bomber != 0) sb.AppendFormat("爆装 {0:+0;-0}\r\n", eq.Bomber); + sb.AppendLine("(右クリックで図鑑)"); + + ToolTipInfo.SetToolTip(Equipments[i], sb.ToString()); + } + } + + } + else if (i < ship.SlotSize) + { + Equipments[i].Text = "(なし)"; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; + + } + else + { + Equipments[i].Text = ""; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; + } + } + + TableEquipment.ResumeLayout(); + + + //arsenal + TableArsenal.SuspendLayout(); + BuildingTime.Text = DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)); + + MaterialFuel.Text = ship.Material[0].ToString(); + MaterialAmmo.Text = ship.Material[1].ToString(); + MaterialSteel.Text = ship.Material[2].ToString(); + MaterialBauxite.Text = ship.Material[3].ToString(); + + PowerUpFirepower.Text = ship.PowerUp[0].ToString(); + PowerUpTorpedo.Text = ship.PowerUp[1].ToString(); + PowerUpAA.Text = ship.PowerUp[2].ToString(); + PowerUpArmor.Text = ship.PowerUp[3].ToString(); + + TableArsenal.ResumeLayout(); + + + //remodel + if (!ship.IsAbyssalShip) + { + + TableRemodel.SuspendLayout(); + + if (ship.RemodelBeforeShipID == 0) + { + RemodelBeforeShipName.Text = "(なし)"; + ToolTipInfo.SetToolTip(RemodelBeforeShipName, null); + RemodelBeforeLevel.Text = ""; + RemodelBeforeLevel.ImageIndex = -1; + ToolTipInfo.SetToolTip(RemodelBeforeLevel, null); + RemodelBeforeAmmo.Text = "-"; + RemodelBeforeSteel.Text = "-"; + } + else + { + ShipDataMaster sbefore = ship.RemodelBeforeShip; + RemodelBeforeShipName.Text = sbefore.Name; + ToolTipInfo.SetToolTip(RemodelBeforeShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); + RemodelBeforeLevel.Text = string.Format("Lv. {0}", sbefore.RemodelAfterLevel); + RemodelBeforeLevel.ImageIndex = GetRemodelItemImageIndex(sbefore); + ToolTipInfo.SetToolTip(RemodelBeforeLevel, GetRemodelItem(sbefore)); + RemodelBeforeAmmo.Text = sbefore.RemodelAmmo.ToString(); + RemodelBeforeSteel.Text = sbefore.RemodelSteel.ToString(); + } + + if (ship.RemodelAfterShipID == 0) + { + RemodelAfterShipName.Text = "(なし)"; + ToolTipInfo.SetToolTip(RemodelAfterShipName, null); + RemodelAfterLevel.Text = ""; + RemodelAfterLevel.ImageIndex = -1; + ToolTipInfo.SetToolTip(RemodelAfterLevel, null); + RemodelAfterAmmo.Text = "-"; + RemodelAfterSteel.Text = "-"; + } + else + { + RemodelAfterShipName.Text = ship.RemodelAfterShip.Name; + ToolTipInfo.SetToolTip(RemodelAfterShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); + RemodelAfterLevel.Text = string.Format("Lv. {0}", ship.RemodelAfterLevel); + RemodelAfterLevel.ImageIndex = GetRemodelItemImageIndex(ship); + ToolTipInfo.SetToolTip(RemodelAfterLevel, GetRemodelItem(ship)); + RemodelAfterAmmo.Text = ship.RemodelAmmo.ToString(); + RemodelAfterSteel.Text = ship.RemodelSteel.ToString(); + } + TableRemodel.ResumeLayout(); + + + TableRemodel.Visible = true; + TableBattle.Visible = false; + + + } + else + { + + TableBattle.SuspendLayout(); + + AirSuperiority.Text = Calculator.GetAirSuperiority(ship).ToString(); + DayAttack.Text = Constants.GetDayAttackKind(Calculator.GetDayAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); + NightAttack.Text = Constants.GetNightAttackKind(Calculator.GetNightAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); + + TableBattle.ResumeLayout(); + + TableRemodel.Visible = false; + TableBattle.Visible = true; + + } + + + if (ShipBanner.Image != null) + { + var img = ShipBanner.Image; + ShipBanner.Image = null; + img.Dispose(); + } + if (!ImageLoader.IsBusy) + { + loadingResourceShipID = ship.ShipID; + ImageLoader.RunWorkerAsync(ship.ResourceName); + } + + + + BasePanelShipGirl.ResumeLayout(); + BasePanelShipGirl.Visible = true; + + + this.Text = "艦船図鑑 - " + ship.NameWithClass; + + } + + + private void UpdateLevelParameter(int shipID) + { + + ShipDataMaster ship = KCDatabase.Instance.MasterShips[shipID]; + + if (ship == null) + return; + + if (!ship.IsAbyssalShip) + { + ASWLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.ASW); + EvasionLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.Evasion); + LOSLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.LOS); + ASWLevel.Visible = + ASWSeparater.Visible = + EvasionLevel.Visible = + EvasionSeparater.Visible = + LOSLevel.Visible = + LOSSeparater.Visible = true; + + } + else + { + ASWLevel.Visible = + ASWSeparater.Visible = + EvasionLevel.Visible = + EvasionSeparater.Visible = + LOSLevel.Visible = + LOSSeparater.Visible = false; + } + } - private string EstimateParameter(int level, ShipParameterRecord.Parameter param) - { + private string EstimateParameter(int level, ShipParameterRecord.Parameter param) + { - if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) - return "???"; + if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) + return "???"; - int min = (int)(param.MinimumEstMin + (param.Maximum - param.MinimumEstMin) * level / 99.0); - int max = (int)(param.MinimumEstMax + (param.Maximum - param.MinimumEstMax) * level / 99.0); + int min = (int)(param.MinimumEstMin + (param.Maximum - param.MinimumEstMin) * level / 99.0); + int max = (int)(param.MinimumEstMax + (param.Maximum - param.MinimumEstMax) * level / 99.0); - if (min == max) - return min.ToString(); - else - return $"{Math.Min(min, max)}~{Math.Max(min, max)}"; - } + if (min == max) + return min.ToString(); + else + return $"{Math.Min(min, max)}~{Math.Max(min, max)}"; + } - private string GetParameterMinBound(ShipParameterRecord.Parameter param) - { + private string GetParameterMinBound(ShipParameterRecord.Parameter param) + { - if (param == null || param.MinimumEstMax == ShipParameterRecord.Parameter.MaximumDefault) - return "???"; - else if (param.MinimumEstMin == param.MinimumEstMax) - return param.MinimumEstMin.ToString(); - else if (param.MinimumEstMin == ShipParameterRecord.Parameter.MinimumDefault && param.MinimumEstMax == param.Maximum) - return "???"; - else - return $"{param.MinimumEstMin}~{param.MinimumEstMax}"; + if (param == null || param.MinimumEstMax == ShipParameterRecord.Parameter.MaximumDefault) + return "???"; + else if (param.MinimumEstMin == param.MinimumEstMax) + return param.MinimumEstMin.ToString(); + else if (param.MinimumEstMin == ShipParameterRecord.Parameter.MinimumDefault && param.MinimumEstMax == param.Maximum) + return "???"; + else + return $"{param.MinimumEstMin}~{param.MinimumEstMax}"; - } + } - private string GetParameterMax(ShipParameterRecord.Parameter param) - { + private string GetParameterMax(ShipParameterRecord.Parameter param) + { - if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) - return "???"; - else - return param.Maximum.ToString(); + if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) + return "???"; + else + return param.Maximum.ToString(); - } + } - private void ParameterLevel_ValueChanged(object sender, EventArgs e) - { - if (_shipID != -1) - { - LevelTimer.Start(); - //UpdateLevelParameter( _shipID ); - } - } + private void ParameterLevel_ValueChanged(object sender, EventArgs e) + { + if (_shipID != -1) + { + LevelTimer.Start(); + //UpdateLevelParameter( _shipID ); + } + } - private void LevelTimer_Tick(object sender, EventArgs e) - { - if (_shipID != -1) - UpdateLevelParameter(_shipID); - } + private void LevelTimer_Tick(object sender, EventArgs e) + { + if (_shipID != -1) + UpdateLevelParameter(_shipID); + } - private void TableParameterMain_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - /*/ + private void TableParameterMain_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + /*/ if ( e.Column == 0 ) e.Graphics.DrawLine( Pens.Silver, e.CellBounds.Right - 1, e.CellBounds.Y, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1 ); //*/ - } + } - private void TableParameterSub_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableParameterSub_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableConsumption_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableConsumption_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableEquipment_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableEquipment_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableArsenal_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableArsenal_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableRemodel_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - if (e.Row % 2 == 1) - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableRemodel_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + if (e.Row % 2 == 1) + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void RemodelBeforeShipName_MouseClick(object sender, MouseEventArgs e) - { + private void RemodelBeforeShipName_MouseClick(object sender, MouseEventArgs e) + { - if (_shipID == -1) return; - var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (_shipID == -1) return; + var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null && ship.RemodelBeforeShipID != 0) - { + if (ship != null && ship.RemodelBeforeShipID != 0) + { - if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) - new DialogAlbumMasterShip(ship.RemodelBeforeShipID).Show(Owner); + if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) + new DialogAlbumMasterShip(ship.RemodelBeforeShipID).Show(Owner); - else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) - UpdateAlbumPage(ship.RemodelBeforeShipID); - } - } + else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) + UpdateAlbumPage(ship.RemodelBeforeShipID); + } + } - private void RemodelAfterShipName_MouseClick(object sender, MouseEventArgs e) - { + private void RemodelAfterShipName_MouseClick(object sender, MouseEventArgs e) + { - if (_shipID == -1) return; - var ship = KCDatabase.Instance.MasterShips[_shipID]; - - if (ship != null && ship.RemodelAfterShipID != 0) - { - - if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) - new DialogAlbumMasterShip(ship.RemodelAfterShipID).Show(Owner); - - else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) - UpdateAlbumPage(ship.RemodelAfterShipID); - } - } - - - - private void Equipment_MouseClick(object sender, MouseEventArgs e) - { - - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - - for (int i = 0; i < Equipments.Length; i++) - { - if (sender == Equipments[i]) - { - - if (_shipID != -1) - { - ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; - - if (ship != null && ship.DefaultSlot != null && i < ship.DefaultSlot.Count && KCDatabase.Instance.MasterEquipments.ContainsKey(ship.DefaultSlot[i])) - { - Cursor = Cursors.AppStarting; - new DialogAlbumMasterEquipment(ship.DefaultSlot[i]).Show(Owner); - Cursor = Cursors.Default; - } - } - } - } - - } - } - - - private string GetRemodelItem(ShipDataMaster ship) - { - StringBuilder sb = new StringBuilder(); - if (ship.NeedBlueprint > 0) - sb.AppendLine("改装設計図: " + ship.NeedBlueprint); - if (ship.NeedCatapult > 0) - sb.AppendLine("試製甲板カタパルト: " + ship.NeedCatapult); - - return sb.ToString(); - } - - - private void StripMenu_File_OutputCSVUser_Click(object sender, EventArgs e) - { - - if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - - try - { - - using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) - { - - sw.WriteLine("艦船ID,図鑑番号,艦種,艦名,読み,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,改装段階,耐久初期,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期,対潜最大,回避初期,回避最大,索敵初期,索敵最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン"); - - foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) - { - - if (ship.Name == "なし") continue; - - sw.WriteLine(string.Join(",", - ship.ShipID, - ship.AlbumNo, - ship.ShipTypeName, - ship.Name, - ship.NameReading, - ship.RemodelBeforeShipID > 0 ? ship.RemodelBeforeShip.Name : "-", - ship.RemodelAfterShipID > 0 ? ship.RemodelAfterShip.Name : "-", - ship.RemodelAfterLevel, - ship.RemodelAmmo, - ship.RemodelSteel, - ship.NeedBlueprint > 0 ? ship.NeedBlueprint + "枚" : "-", - ship.NeedCatapult > 0 ? ship.NeedCatapult + "個" : "-", - ship.RemodelTier, - ship.HPMin, - ship.HPMaxMarried, - ship.FirepowerMin, - ship.FirepowerMax, - ship.TorpedoMin, - ship.TorpedoMax, - ship.AAMin, - ship.AAMax, - ship.ArmorMin, - ship.ArmorMax, - ship.ASW != null && !ship.ASW.IsMinimumDefault ? ship.ASW.Minimum.ToString() : "???", - ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum.ToString() : "???", - ship.Evasion != null && !ship.Evasion.IsMinimumDefault ? ship.Evasion.Minimum.ToString() : "???", - ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum.ToString() : "???", - ship.LOS != null && !ship.LOS.IsMinimumDefault ? ship.LOS.Minimum.ToString() : "???", - ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum.ToString() : "???", - ship.LuckMin, - ship.LuckMax, - Constants.GetSpeed(ship.Speed), - Constants.GetRange(ship.Range), - Constants.GetShipRarity(ship.Rarity), - ship.SlotSize, - ship.Aircraft[0], - ship.Aircraft[1], - ship.Aircraft[2], - ship.Aircraft[3], - ship.Aircraft[4], - ship.DefaultSlot != null ? (ship.DefaultSlot[0] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[0]].Name : (ship.SlotSize > 0 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[1] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[1]].Name : (ship.SlotSize > 1 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[2] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[2]].Name : (ship.SlotSize > 2 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[3] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[3]].Name : (ship.SlotSize > 3 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[4] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[4]].Name : (ship.SlotSize > 4 ? "(なし)" : "")) : "???", - DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)), - ship.Material[0], - ship.Material[1], - ship.Material[2], - ship.Material[3], - ship.PowerUp[0], - ship.PowerUp[1], - ship.PowerUp[2], - ship.PowerUp[3], - ship.MessageGet.Replace("\r\n", "
"), - ship.MessageAlbum.Replace("\r\n", "
"), - ship.Fuel, - ship.Ammo, - Constants.GetVoiceFlag(ship.VoiceFlag), - ship.ResourceName, - ship.ResourceGraphicVersion, - ship.ResourceVoiceVersion, - ship.ResourcePortVoiceVersion - )); - - } - - } - - } - catch (Exception ex) - { - - Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); - MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - - } - - } - - - private void StripMenu_File_OutputCSVData_Click(object sender, EventArgs e) - { - - if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - - try - { - - using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) - { - - sw.WriteLine(string.Format("艦船ID,図鑑番号,艦名,読み,艦種,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,改装段階,耐久初期,耐久最大,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期最小,対潜初期最大,対潜最大,対潜{0}最小,対潜{0}最大,回避初期最小,回避初期最大,回避最大,回避{0}最小,回避{0}最大,索敵初期最小,索敵初期最大,索敵最大,索敵{0}最小,索敵{0}最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン", ExpTable.ShipMaximumLevel)); - - foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) - { - - sw.WriteLine(string.Join(",", - ship.ShipID, - ship.AlbumNo, - ship.Name, - ship.NameReading, - (int)ship.ShipType, - ship.RemodelBeforeShipID, - ship.RemodelAfterShipID, - ship.RemodelAfterLevel, - ship.RemodelAmmo, - ship.RemodelSteel, - ship.NeedBlueprint, - ship.NeedCatapult, - ship.RemodelTier, - ship.HPMin, - ship.HPMax, - ship.HPMaxMarried, - ship.FirepowerMin, - ship.FirepowerMax, - ship.TorpedoMin, - ship.TorpedoMax, - ship.AAMin, - ship.AAMax, - ship.ArmorMin, - ship.ArmorMax, - ship.ASW?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.ASW?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.ASW?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.ASW?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.ASW?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.Evasion?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.Evasion?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.Evasion?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.Evasion?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.Evasion?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LOS?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.LOS?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LOS?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LOS?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.LOS?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LuckMin, - ship.LuckMax, - ship.Speed, - ship.Range, - ship.Rarity, - ship.SlotSize, - ship.Aircraft[0], - ship.Aircraft[1], - ship.Aircraft[2], - ship.Aircraft[3], - ship.Aircraft[4], - ship.DefaultSlot?[0] ?? -1, - ship.DefaultSlot?[1] ?? -1, - ship.DefaultSlot?[2] ?? -1, - ship.DefaultSlot?[3] ?? -1, - ship.DefaultSlot?[4] ?? -1, - ship.BuildingTime, - ship.Material[0], - ship.Material[1], - ship.Material[2], - ship.Material[3], - ship.PowerUp[0], - ship.PowerUp[1], - ship.PowerUp[2], - ship.PowerUp[3], - ship.MessageGet.Replace("\r\n", "
"), - ship.MessageAlbum.Replace("\r\n", "
"), - ship.Fuel, - ship.Ammo, - ship.VoiceFlag, - ship.ResourceName, - ship.ResourceGraphicVersion, - ship.ResourceVoiceVersion, - ship.ResourcePortVoiceVersion - )); - - } - - } - - } - catch (Exception ex) - { - - Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); - MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - - } - - } - - - - private void DialogAlbumMasterShip_FormClosed(object sender, FormClosedEventArgs e) - { - - ResourceManager.DestroyIcon(Icon); - - } - - - - private void Description_Click(object sender, EventArgs e) - { - - int tag = Description.Tag as int? ?? 0; - ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; - - if (ship == null) return; - - if (tag == 0 && ship.MessageAlbum.Length > 0) - { - Description.Text = ship.MessageAlbum; - Description.Tag = 1; - - } - else - { - Description.Text = ship.MessageGet; - Description.Tag = 0; - } - } - - - private void ResourceName_MouseClick(object sender, MouseEventArgs e) - { - - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - { - Clipboard.SetData(DataFormats.StringFormat, ship.ResourceName); - } - } + if (_shipID == -1) return; + var ship = KCDatabase.Instance.MasterShips[_shipID]; - } + if (ship != null && ship.RemodelAfterShipID != 0) + { + + if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) + new DialogAlbumMasterShip(ship.RemodelAfterShipID).Show(Owner); + + else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) + UpdateAlbumPage(ship.RemodelAfterShipID); + } + } + + + + private void Equipment_MouseClick(object sender, MouseEventArgs e) + { + + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + + for (int i = 0; i < Equipments.Length; i++) + { + if (sender == Equipments[i]) + { + + if (_shipID != -1) + { + ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; + + if (ship != null && ship.DefaultSlot != null && i < ship.DefaultSlot.Count && KCDatabase.Instance.MasterEquipments.ContainsKey(ship.DefaultSlot[i])) + { + Cursor = Cursors.AppStarting; + new DialogAlbumMasterEquipment(ship.DefaultSlot[i]).Show(Owner); + Cursor = Cursors.Default; + } + } + } + } + + } + } + + + private static int GetRemodelItemImageIndex(ShipDataMaster ship) + { + return + ship.NeedCatapult > 0 ? (int)ResourceManager.IconContent.ItemCatapult : + ship.NeedActionReport > 0 ? (int)ResourceManager.IconContent.ItemActionReport : + ship.NeedBlueprint > 0 ? (int)ResourceManager.IconContent.ItemBlueprint : + -1; + } + + private static string GetRemodelItem(ShipDataMaster ship) + { + StringBuilder sb = new StringBuilder(); + if (ship.NeedBlueprint > 0) + sb.AppendLine("改装設計図: " + ship.NeedBlueprint); + if (ship.NeedCatapult > 0) + sb.AppendLine("試製甲板カタパルト: " + ship.NeedCatapult); + if (ship.NeedActionReport > 0) + sb.AppendLine("戦闘詳報: " + ship.NeedActionReport); + + return sb.ToString(); + } + + + private void StripMenu_File_OutputCSVUser_Click(object sender, EventArgs e) + { + + if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + + try + { + + using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) + { + + sw.WriteLine("艦船ID,図鑑番号,艦型,艦種,艦名,読み,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,戦闘詳報,改装段階,耐久初期,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期,対潜最大,回避初期,回避最大,索敵初期,索敵最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン"); + + foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) + { + + if (ship.Name == "なし") continue; + + sw.WriteLine(string.Join(",", + ship.ShipID, + ship.AlbumNo, + ship.IsAbyssalShip ? "深海棲艦" : Constants.GetShipClass(ship.ShipClass), + ship.ShipTypeName, + ship.Name, + ship.NameReading, + ship.RemodelBeforeShipID > 0 ? ship.RemodelBeforeShip.Name : "-", + ship.RemodelAfterShipID > 0 ? ship.RemodelAfterShip.Name : "-", + ship.RemodelAfterLevel, + ship.RemodelAmmo, + ship.RemodelSteel, + ship.NeedBlueprint > 0 ? ship.NeedBlueprint + "枚" : "-", + ship.NeedCatapult > 0 ? ship.NeedCatapult + "個" : "-", + ship.NeedActionReport > 0 ? ship.NeedActionReport + "枚" : "-", + ship.RemodelTier, + ship.HPMin, + ship.HPMaxMarried, + ship.FirepowerMin, + ship.FirepowerMax, + ship.TorpedoMin, + ship.TorpedoMax, + ship.AAMin, + ship.AAMax, + ship.ArmorMin, + ship.ArmorMax, + ship.ASW != null && !ship.ASW.IsMinimumDefault ? ship.ASW.Minimum.ToString() : "???", + ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum.ToString() : "???", + ship.Evasion != null && !ship.Evasion.IsMinimumDefault ? ship.Evasion.Minimum.ToString() : "???", + ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum.ToString() : "???", + ship.LOS != null && !ship.LOS.IsMinimumDefault ? ship.LOS.Minimum.ToString() : "???", + ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum.ToString() : "???", + ship.LuckMin, + ship.LuckMax, + Constants.GetSpeed(ship.Speed), + Constants.GetRange(ship.Range), + Constants.GetShipRarity(ship.Rarity), + ship.SlotSize, + ship.Aircraft[0], + ship.Aircraft[1], + ship.Aircraft[2], + ship.Aircraft[3], + ship.Aircraft[4], + ship.DefaultSlot != null ? (ship.DefaultSlot[0] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[0]].Name : (ship.SlotSize > 0 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[1] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[1]].Name : (ship.SlotSize > 1 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[2] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[2]].Name : (ship.SlotSize > 2 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[3] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[3]].Name : (ship.SlotSize > 3 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[4] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[4]].Name : (ship.SlotSize > 4 ? "(なし)" : "")) : "???", + DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)), + ship.Material[0], + ship.Material[1], + ship.Material[2], + ship.Material[3], + ship.PowerUp[0], + ship.PowerUp[1], + ship.PowerUp[2], + ship.PowerUp[3], + ship.MessageGet.Replace("\r\n", "
"), + ship.MessageAlbum.Replace("\r\n", "
"), + ship.Fuel, + ship.Ammo, + Constants.GetVoiceFlag(ship.VoiceFlag), + ship.ResourceName, + ship.ResourceGraphicVersion, + ship.ResourceVoiceVersion, + ship.ResourcePortVoiceVersion + )); + + } + + } + + } + catch (Exception ex) + { + + Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); + MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + } + + + private void StripMenu_File_OutputCSVData_Click(object sender, EventArgs e) + { + + if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + + try + { + + using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) + { + + sw.WriteLine(string.Format("艦船ID,図鑑番号,艦名,読み,艦種,艦型,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,戦闘詳報,改装段階,耐久初期,耐久最大,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期最小,対潜初期最大,対潜最大,対潜{0}最小,対潜{0}最大,回避初期最小,回避初期最大,回避最大,回避{0}最小,回避{0}最大,索敵初期最小,索敵初期最大,索敵最大,索敵{0}最小,索敵{0}最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン", ExpTable.ShipMaximumLevel)); + + foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) + { + + sw.WriteLine(string.Join(",", + ship.ShipID, + ship.AlbumNo, + ship.Name, + ship.NameReading, + (int)ship.ShipType, + ship.ShipClass, + ship.RemodelBeforeShipID, + ship.RemodelAfterShipID, + ship.RemodelAfterLevel, + ship.RemodelAmmo, + ship.RemodelSteel, + ship.NeedBlueprint, + ship.NeedCatapult, + ship.NeedActionReport, + ship.RemodelTier, + ship.HPMin, + ship.HPMax, + ship.HPMaxMarried, + ship.FirepowerMin, + ship.FirepowerMax, + ship.TorpedoMin, + ship.TorpedoMax, + ship.AAMin, + ship.AAMax, + ship.ArmorMin, + ship.ArmorMax, + ship.ASW?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.ASW?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.ASW?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.ASW?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.ASW?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.Evasion?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.Evasion?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.Evasion?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.Evasion?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.Evasion?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LOS?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.LOS?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LOS?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LOS?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.LOS?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LuckMin, + ship.LuckMax, + ship.Speed, + ship.Range, + ship.Rarity, + ship.SlotSize, + ship.Aircraft[0], + ship.Aircraft[1], + ship.Aircraft[2], + ship.Aircraft[3], + ship.Aircraft[4], + ship.DefaultSlot?[0] ?? -1, + ship.DefaultSlot?[1] ?? -1, + ship.DefaultSlot?[2] ?? -1, + ship.DefaultSlot?[3] ?? -1, + ship.DefaultSlot?[4] ?? -1, + ship.BuildingTime, + ship.Material[0], + ship.Material[1], + ship.Material[2], + ship.Material[3], + ship.PowerUp[0], + ship.PowerUp[1], + ship.PowerUp[2], + ship.PowerUp[3], + ship.MessageGet.Replace("\r\n", "
"), + ship.MessageAlbum.Replace("\r\n", "
"), + ship.Fuel, + ship.Ammo, + ship.VoiceFlag, + ship.ResourceName, + ship.ResourceGraphicVersion, + ship.ResourceVoiceVersion, + ship.ResourcePortVoiceVersion + )); + + } + + } + + } + catch (Exception ex) + { + + Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); + MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + } + + + + private void DialogAlbumMasterShip_FormClosed(object sender, FormClosedEventArgs e) + { + + ResourceManager.DestroyIcon(Icon); + + } + + + + private void Description_Click(object sender, EventArgs e) + { + + int tag = Description.Tag as int? ?? 0; + ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; + + if (ship == null) return; + + if (tag == 0 && ship.MessageAlbum.Length > 0) + { + Description.Text = ship.MessageAlbum; + Description.Tag = 1; + + } + else + { + Description.Text = ship.MessageGet; + Description.Tag = 0; + } + } + + + private void ResourceName_MouseClick(object sender, MouseEventArgs e) + { + + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + { + Clipboard.SetData(DataFormats.StringFormat, ship.ResourceName); + } + } + } - private void StripMenu_Edit_EditParameter_Click(object sender, EventArgs e) - { - if (_shipID <= 0) - { - MessageBox.Show("艦船を選択してください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); - return; - } + private void StripMenu_Edit_EditParameter_Click(object sender, EventArgs e) + { - using (var dialog = new DialogAlbumShipParameter(_shipID)) - { - dialog.ShowDialog(this); - UpdateAlbumPage(_shipID); - } + if (_shipID <= 0) + { + MessageBox.Show("艦船を選択してください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + return; + } - } + using (var dialog = new DialogAlbumShipParameter(_shipID)) + { + dialog.ShowDialog(this); + UpdateAlbumPage(_shipID); + } + } - private void ImageLoader_DoWork(object sender, DoWorkEventArgs e) - { - string resourceName = e.Argument as string; + private void ImageLoader_DoWork(object sender, DoWorkEventArgs e) + { - //System.Threading.Thread.Sleep( 2000 ); // for test + string resourceName = e.Argument as string; - try - { + //System.Threading.Thread.Sleep( 2000 ); // for test - var img = SwfHelper.GetShipSwfImage(resourceName, SwfHelper.ShipResourceCharacterID.BannerNormal); + try + { - if (img.Size == SwfHelper.ShipBannerSize) - { - e.Result = img; - } - else - { - img.Dispose(); - e.Result = null; - } - } - catch (Exception) - { - e.Result = null; - } + var img = SwfHelper.GetShipSwfImage(resourceName, SwfHelper.ShipResourceCharacterID.BannerNormal); - } + if (img.Size == SwfHelper.ShipBannerSize) + { + e.Result = img; + } + else + { + img.Dispose(); + e.Result = null; + } + } + catch (Exception) + { + e.Result = null; + } - private void ImageLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { + } - if (ShipBanner.Image != null) - { - var img = ShipBanner.Image; - ShipBanner.Image = null; - img.Dispose(); - } - - if (loadingResourceShipID != _shipID) - { - if (e.Result != null) - ((Bitmap)e.Result).Dispose(); - - if (!ImageLoader.IsBusy) - { - loadingResourceShipID = _shipID; - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - ImageLoader.RunWorkerAsync(ship.ResourceName); - } - - return; - } - - if (e.Result != null) - { - ShipBanner.Image = e.Result as Bitmap; - loadingResourceShipID = -1; - } - - } - - - - private void TextSearch_TextChanged(object sender, EventArgs e) - { - - if (string.IsNullOrWhiteSpace(TextSearch.Text)) - return; - - string searchWord = ToHiragana(TextSearch.Text.ToLower()); - var target = - ShipView.Rows.OfType() - .Select(r => KCDatabase.Instance.MasterShips[(int)r.Cells[ShipView_ShipID.Index].Value]) - .FirstOrDefault( - ship => - ToHiragana(ship.NameWithClass.ToLower()).StartsWith(searchWord) || - ToHiragana(ship.NameReading.ToLower()).StartsWith(searchWord)); - - if (target != null) - { - ShipView.FirstDisplayedScrollingRowIndex = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == target.ShipID).Index; - } - } - - public static string ToHiragana(string str) - { - // あまり深いことは考えずにやる - char hiraganaHead = '\x3041'; - char katakanaHead = '\x30a1'; - char katakanaTail = '\x30ff'; - - char[] chars = str.ToCharArray(); - for (int i = 0; i < chars.Length; i++) - { - if (katakanaHead <= chars[i] && chars[i] <= katakanaTail) - { // is katakana - chars[i] = (char)((int)chars[i] - (int)katakanaHead + (int)hiraganaHead); - } - } - - return new string(chars); - } - - private void TextSearch_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode == Keys.Enter) - { - TextSearch_TextChanged(sender, e); - e.SuppressKeyPress = true; - e.Handled = true; - } - } - - private void StripMenu_Edit_CopyShipName_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - Clipboard.SetText(ship.NameWithClass); - else - System.Media.SystemSounds.Exclamation.Play(); - } - - private void ShipName_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - Clipboard.SetText(ship.NameWithClass); - else - System.Media.SystemSounds.Exclamation.Play(); - } - } - - private void StripMenu_Edit_CopyShipData_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship == null) - { - System.Media.SystemSounds.Exclamation.Play(); - return; - } - - var sb = new StringBuilder(); - - var slot = (ship.DefaultSlot ?? Enumerable.Repeat(-2, 5)).ToArray(); - - sb.AppendFormat("{0} {1}\r\n", ship.ShipTypeName, ship.NameWithClass); - sb.AppendFormat("ID: {0} / 図鑑番号: {1} / リソース: {2} ver. {3} / {4} / {5} ({6})\r\n", ship.ShipID, ship.AlbumNo, - ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, - Constants.GetVoiceFlag(ship.VoiceFlag)); - sb.AppendLine(); - if (!ship.IsAbyssalShip) - { - sb.AppendFormat("耐久: {0} / {1}\r\n", ship.HPMin, ship.HPMaxMarried); - sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax); - sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax); - sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax); - sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax); - sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMinBound(ship.ASW), GetParameterMax(ship.ASW)); - sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMinBound(ship.Evasion), GetParameterMax(ship.Evasion)); - sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMinBound(ship.LOS), GetParameterMax(ship.LOS)); - sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin, ship.LuckMax); - sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), Constants.GetRange(ship.Range)); - sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); - sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); - } - else - { - var availableEquipments = slot.Select(id => KCDatabase.Instance.MasterEquipments[id]).Where(eq => eq != null); - int luckSum = ship.LuckMax + availableEquipments.Sum(eq => eq.Luck); - sb.AppendFormat("耐久: {0}\r\n", ship.HPMin > 0 ? ship.HPMin.ToString() : "???"); - sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax + availableEquipments.Sum(eq => eq.Firepower)); - sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax + availableEquipments.Sum(eq => eq.Torpedo)); - sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax + availableEquipments.Sum(eq => eq.AA)); - sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax + availableEquipments.Sum(eq => eq.Armor)); - sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMax(ship.ASW), (ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum : 0) + availableEquipments.Sum(eq => eq.ASW)); - sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMax(ship.Evasion), (ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum : 0) + availableEquipments.Sum(eq => eq.Evasion)); - sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMax(ship.LOS), (ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum : 0) + availableEquipments.Sum(eq => eq.LOS)); - sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin > 0 ? ship.LuckMin.ToString() : "???", luckSum > 0 ? luckSum.ToString() : "???"); - sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), - Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0))); - if (ship.Fuel > 0 || ship.Ammo > 0) - sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); - if (ship.Rarity > 0) - sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); - } - sb.AppendLine(); - sb.AppendLine("初期装備:"); - { - for (int i = 0; i < slot.Length; i++) - { - string name; - var eq = KCDatabase.Instance.MasterEquipments[slot[i]]; - if (eq == null && i >= ship.SlotSize) - continue; - - if (eq != null) - name = eq.Name; - else if (slot[i] == -1) - name = "(なし)"; - else - name = "(不明)"; - - sb.AppendFormat("[{0}] {1}\r\n", ship.Aircraft[i], name); - } - } - sb.AppendLine(); - if (!ship.IsAbyssalShip) - { - sb.AppendFormat("建造時間: {0}\r\n", DateTimeHelper.ToTimeRemainString(TimeSpan.FromMinutes(ship.BuildingTime))); - sb.AppendFormat("解体資源: {0}\r\n", string.Join(" / ", ship.Material)); - sb.AppendFormat("改修強化: {0}\r\n", string.Join(" / ", ship.PowerUp)); - if (ship.RemodelBeforeShipID != 0) - { - var before = ship.RemodelBeforeShip; - var append = new List(4) - { - "弾薬 " + before.RemodelAmmo, - "鋼材 " + before.RemodelSteel - }; - if (before.NeedBlueprint > 0) - append.Add("要改装設計図"); - if (before.NeedCatapult > 0) - append.Add("要カタパルト"); - sb.AppendFormat("改造前: {0} Lv. {1} ({2})\r\n", - before.NameWithClass, before.RemodelAfterLevel, string.Join(", ", append)); - } - else - { - sb.AppendLine("改造前: (なし)"); - } - if (ship.RemodelAfterShipID != 0) - { - var append = new List(4) - { - "弾薬 " + ship.RemodelAmmo, - "鋼材 " + ship.RemodelSteel - }; - if (ship.NeedBlueprint > 0) - append.Add("要改装設計図"); - if (ship.NeedCatapult > 0) - append.Add("要カタパルト"); - sb.AppendFormat("改造後: {0} Lv. {1} ({2})\r\n", - ship.RemodelAfterShip.NameWithClass, ship.RemodelAfterLevel, string.Join(", ", append)); - } - else - { - sb.AppendLine("改造後: (なし)"); - } - sb.AppendLine(); - sb.AppendFormat("図鑑文章: \r\n{0}\r\n\r\n入手文章: \r\n{1}\r\n\r\n", - !string.IsNullOrWhiteSpace(ship.MessageAlbum) ? ship.MessageAlbum : "(不明)", - !string.IsNullOrWhiteSpace(ship.MessageGet) ? ship.MessageGet : "(不明)"); - } - - sb.AppendLine("出現海域:"); - { - string result = GetAppearingArea(ship.ShipID); - if (string.IsNullOrEmpty(result)) - result = "(不明)"; - sb.AppendLine(result); - } - - Clipboard.SetText(sb.ToString()); - } - - - - private string GetAppearingArea(int shipID) - { - - var ship = KCDatabase.Instance.MasterShips[shipID]; - if (ship == null) - return string.Empty; - - var sb = new StringBuilder(); - - if (!ship.IsAbyssalShip) - { - - foreach (var record in RecordManager.Instance.ShipDrop.Record - .Where(s => s.ShipID == shipID && s.EnemyFleetID != 0) - .Select(s => new - { - s.MapAreaID, - s.MapInfoID, - s.CellID, - s.Difficulty, - EnemyFleetName = RecordManager.Instance.EnemyFleet.Record.ContainsKey(s.EnemyFleetID) ? - RecordManager.Instance.EnemyFleet.Record[s.EnemyFleetID].FleetName : "敵艦隊名不明" - }) - .Distinct() - .OrderBy(r => r.MapAreaID) - .ThenBy(r => r.MapInfoID) - .ThenBy(r => r.CellID) - .ThenBy(r => r.Difficulty) - ) - { - sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", - record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); - } - - foreach (var record in RecordManager.Instance.Construction.Record - .Where(s => s.ShipID == shipID) - .Select(s => new - { - s.Fuel, - s.Ammo, - s.Steel, - s.Bauxite, - s.DevelopmentMaterial - }) - .Distinct() - .OrderBy(r => r.Fuel) - .ThenBy(r => r.Ammo) - .ThenBy(r => r.Steel) - .ThenBy(r => r.Bauxite) - .ThenBy(r => r.DevelopmentMaterial) - ) - { - sb.AppendFormat("建造 {0} / {1} / {2} / {3} - {4}\r\n", - record.Fuel, record.Ammo, record.Steel, record.Bauxite, record.DevelopmentMaterial); - } - - } - else - { - - foreach (var record in RecordManager.Instance.EnemyFleet.Record.Values - .Where(r => r.FleetMember.Contains(shipID)) - .Select(s => new - { - s.MapAreaID, - s.MapInfoID, - s.CellID, - s.Difficulty, - EnemyFleetName = !string.IsNullOrWhiteSpace(s.FleetName) ? s.FleetName : "敵艦隊名不明" - }) - .Distinct() - .OrderBy(r => r.MapAreaID) - .ThenBy(r => r.MapInfoID) - .ThenBy(r => r.CellID) - .ThenBy(r => r.Difficulty) - ) - { - sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", - record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); - } - - } - - return sb.ToString(); - } - - private void StripMenu_View_ShowAppearingArea_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship == null) - { - System.Media.SystemSounds.Exclamation.Play(); - return; - } - - string result = GetAppearingArea(ship.ShipID); - - if (string.IsNullOrEmpty(result)) - result = ship.NameWithClass + " の出現海域は不明です。"; - - MessageBox.Show(result, "出現海域検索", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - - - private void ShipBanner_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - - StripMenu_View_ShowShipGraphicViewer.PerformClick(); - } - } - - private void StripMenu_View_ShowShipGraphicViewer_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - { - - var pathlist = new LinkedList(); - pathlist.AddLast(SwfHelper.GetShipResourcePath(ship.ResourceName)); - - foreach (var rec in RecordManager.Instance.ShipParameter.Record.Values.Where(r => r.OriginalCostumeShipID == _shipID)) - { - string path = SwfHelper.GetShipResourcePath(rec.ResourceName); - if (path != null) - pathlist.AddLast(path); - } - - var arg = pathlist.Where(p => p != null).ToArray(); - if (arg.Length > 0) - { - new DialogShipGraphicViewer(arg).Show(Owner); - } - else - { - MessageBox.Show("画像リソースが存在しません。以下の手順を踏んでください。\r\n1. 設定→通信→通信内容を保存する 及び SWF を有効にする。\r\n2. キャッシュをクリアし、再読み込みする。\r\n3. 艦これ本体で当該艦を表示させる(図鑑画面を開くなど)。", "ビューア:画像リソース不足", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - } - else - { - MessageBox.Show("対象艦船を指定してください。", "ビューア:対象未指定", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - } - - - private void StripMenu_Edit_GoogleShipName_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship == null) - { - System.Media.SystemSounds.Exclamation.Play(); - return; - } - - try - { - - // google <艦船名> 艦これ - System.Diagnostics.Process.Start(@"https://www.google.co.jp/search?q=" + Uri.EscapeDataString(ship.NameWithClass) + "+%E8%89%A6%E3%81%93%E3%82%8C"); - - } - catch (Exception ex) - { - Utility.ErrorReporter.SendErrorReport(ex, "艦船名の Google 検索に失敗しました。"); - } - } - - } + private void ImageLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + + if (ShipBanner.Image != null) + { + var img = ShipBanner.Image; + ShipBanner.Image = null; + img.Dispose(); + } + + if (loadingResourceShipID != _shipID) + { + if (e.Result != null) + ((Bitmap)e.Result).Dispose(); + + if (!ImageLoader.IsBusy) + { + loadingResourceShipID = _shipID; + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + ImageLoader.RunWorkerAsync(ship.ResourceName); + } + + return; + } + + if (e.Result != null) + { + ShipBanner.Image = e.Result as Bitmap; + loadingResourceShipID = -1; + } + + } + + + + private void TextSearch_TextChanged(object sender, EventArgs e) + { + + if (string.IsNullOrWhiteSpace(TextSearch.Text)) + return; + + string searchWord = ToHiragana(TextSearch.Text.ToLower()); + var target = + ShipView.Rows.OfType() + .Select(r => KCDatabase.Instance.MasterShips[(int)r.Cells[ShipView_ShipID.Index].Value]) + .FirstOrDefault( + ship => + ToHiragana(ship.NameWithClass.ToLower()).StartsWith(searchWord) || + ToHiragana(ship.NameReading.ToLower()).StartsWith(searchWord)); + + if (target != null) + { + ShipView.FirstDisplayedScrollingRowIndex = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == target.ShipID).Index; + } + } + + public static string ToHiragana(string str) + { + // あまり深いことは考えずにやる + char hiraganaHead = '\x3041'; + char katakanaHead = '\x30a1'; + char katakanaTail = '\x30ff'; + + char[] chars = str.ToCharArray(); + for (int i = 0; i < chars.Length; i++) + { + if (katakanaHead <= chars[i] && chars[i] <= katakanaTail) + { // is katakana + chars[i] = (char)((int)chars[i] - (int)katakanaHead + (int)hiraganaHead); + } + } + + return new string(chars); + } + + private void TextSearch_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + TextSearch_TextChanged(sender, e); + e.SuppressKeyPress = true; + e.Handled = true; + } + } + + private void StripMenu_Edit_CopyShipName_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + Clipboard.SetText(ship.NameWithClass); + else + System.Media.SystemSounds.Exclamation.Play(); + } + + private void ShipName_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + Clipboard.SetText(ship.NameWithClass); + else + System.Media.SystemSounds.Exclamation.Play(); + } + } + + private void StripMenu_Edit_CopyShipData_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship == null) + { + System.Media.SystemSounds.Exclamation.Play(); + return; + } + + var sb = new StringBuilder(); + + var slot = (ship.DefaultSlot ?? Enumerable.Repeat(-2, 5)).ToArray(); + + sb.AppendFormat("{0} {1}\r\n", ship.ShipTypeName, ship.NameWithClass); + sb.AppendFormat("ID: {0} / 図鑑番号: {1} / リソース: {2} ver. {3} / {4} / {5} ({6})\r\n", ship.ShipID, ship.AlbumNo, + ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, + Constants.GetVoiceFlag(ship.VoiceFlag)); + sb.AppendLine(); + if (!ship.IsAbyssalShip) + { + sb.AppendFormat("耐久: {0} / {1}\r\n", ship.HPMin, ship.HPMaxMarried); + sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax); + sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax); + sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax); + sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax); + sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMinBound(ship.ASW), GetParameterMax(ship.ASW)); + sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMinBound(ship.Evasion), GetParameterMax(ship.Evasion)); + sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMinBound(ship.LOS), GetParameterMax(ship.LOS)); + sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin, ship.LuckMax); + sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), Constants.GetRange(ship.Range)); + sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); + sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); + } + else + { + var availableEquipments = slot.Select(id => KCDatabase.Instance.MasterEquipments[id]).Where(eq => eq != null); + int luckSum = ship.LuckMax + availableEquipments.Sum(eq => eq.Luck); + sb.AppendFormat("耐久: {0}\r\n", ship.HPMin > 0 ? ship.HPMin.ToString() : "???"); + sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax + availableEquipments.Sum(eq => eq.Firepower)); + sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax + availableEquipments.Sum(eq => eq.Torpedo)); + sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax + availableEquipments.Sum(eq => eq.AA)); + sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax + availableEquipments.Sum(eq => eq.Armor)); + sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMax(ship.ASW), (ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum : 0) + availableEquipments.Sum(eq => eq.ASW)); + sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMax(ship.Evasion), (ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum : 0) + availableEquipments.Sum(eq => eq.Evasion)); + sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMax(ship.LOS), (ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum : 0) + availableEquipments.Sum(eq => eq.LOS)); + sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin > 0 ? ship.LuckMin.ToString() : "???", luckSum > 0 ? luckSum.ToString() : "???"); + sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), + Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0))); + if (ship.Fuel > 0 || ship.Ammo > 0) + sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); + if (ship.Rarity > 0) + sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); + } + sb.AppendLine(); + sb.AppendLine("初期装備:"); + { + for (int i = 0; i < slot.Length; i++) + { + string name; + var eq = KCDatabase.Instance.MasterEquipments[slot[i]]; + if (eq == null && i >= ship.SlotSize) + continue; + + if (eq != null) + name = eq.Name; + else if (slot[i] == -1) + name = "(なし)"; + else + name = "(不明)"; + + sb.AppendFormat("[{0}] {1}\r\n", ship.Aircraft[i], name); + } + } + sb.AppendLine(); + if (!ship.IsAbyssalShip) + { + sb.AppendFormat("建造時間: {0}\r\n", DateTimeHelper.ToTimeRemainString(TimeSpan.FromMinutes(ship.BuildingTime))); + sb.AppendFormat("解体資源: {0}\r\n", string.Join(" / ", ship.Material)); + sb.AppendFormat("改修強化: {0}\r\n", string.Join(" / ", ship.PowerUp)); + if (ship.RemodelBeforeShipID != 0) + { + var before = ship.RemodelBeforeShip; + var append = new List(4) + { + "弾薬 " + before.RemodelAmmo, + "鋼材 " + before.RemodelSteel + }; + if (before.NeedBlueprint > 0) + append.Add("要改装設計図"); + if (before.NeedCatapult > 0) + append.Add("要カタパルト"); + if (before.NeedActionReport > 0) + append.Add("要戦闘詳報"); + + sb.AppendFormat("改造前: {0} Lv. {1} ({2})\r\n", + before.NameWithClass, before.RemodelAfterLevel, string.Join(", ", append)); + } + else + { + sb.AppendLine("改造前: (なし)"); + } + if (ship.RemodelAfterShipID != 0) + { + var append = new List(4) + { + "弾薬 " + ship.RemodelAmmo, + "鋼材 " + ship.RemodelSteel + }; + if (ship.NeedBlueprint > 0) + append.Add("要改装設計図"); + if (ship.NeedCatapult > 0) + append.Add("要カタパルト"); + if (ship.NeedActionReport > 0) + append.Add("要戦闘詳報"); + + sb.AppendFormat("改造後: {0} Lv. {1} ({2})\r\n", + ship.RemodelAfterShip.NameWithClass, ship.RemodelAfterLevel, string.Join(", ", append)); + } + else + { + sb.AppendLine("改造後: (なし)"); + } + sb.AppendLine(); + sb.AppendFormat("図鑑文章: \r\n{0}\r\n\r\n入手文章: \r\n{1}\r\n\r\n", + !string.IsNullOrWhiteSpace(ship.MessageAlbum) ? ship.MessageAlbum : "(不明)", + !string.IsNullOrWhiteSpace(ship.MessageGet) ? ship.MessageGet : "(不明)"); + } + + sb.AppendLine("出現海域:"); + { + string result = GetAppearingArea(ship.ShipID); + if (string.IsNullOrEmpty(result)) + result = "(不明)"; + sb.AppendLine(result); + } + + Clipboard.SetText(sb.ToString()); + } + + + + private string GetAppearingArea(int shipID) + { + + var ship = KCDatabase.Instance.MasterShips[shipID]; + if (ship == null) + return string.Empty; + + var sb = new StringBuilder(); + + if (!ship.IsAbyssalShip) + { + + foreach (var record in RecordManager.Instance.ShipDrop.Record + .Where(s => s.ShipID == shipID && s.EnemyFleetID != 0) + .Select(s => new + { + s.MapAreaID, + s.MapInfoID, + s.CellID, + s.Difficulty, + EnemyFleetName = RecordManager.Instance.EnemyFleet.Record.ContainsKey(s.EnemyFleetID) ? + RecordManager.Instance.EnemyFleet.Record[s.EnemyFleetID].FleetName : "敵艦隊名不明" + }) + .Distinct() + .OrderBy(r => r.MapAreaID) + .ThenBy(r => r.MapInfoID) + .ThenBy(r => r.CellID) + .ThenBy(r => r.Difficulty) + ) + { + sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", + record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); + } + + foreach (var record in RecordManager.Instance.Construction.Record + .Where(s => s.ShipID == shipID) + .Select(s => new + { + s.Fuel, + s.Ammo, + s.Steel, + s.Bauxite, + s.DevelopmentMaterial + }) + .Distinct() + .OrderBy(r => r.Fuel) + .ThenBy(r => r.Ammo) + .ThenBy(r => r.Steel) + .ThenBy(r => r.Bauxite) + .ThenBy(r => r.DevelopmentMaterial) + ) + { + sb.AppendFormat("建造 {0} / {1} / {2} / {3} - {4}\r\n", + record.Fuel, record.Ammo, record.Steel, record.Bauxite, record.DevelopmentMaterial); + } + + } + else + { + + foreach (var record in RecordManager.Instance.EnemyFleet.Record.Values + .Where(r => r.FleetMember.Contains(shipID)) + .Select(s => new + { + s.MapAreaID, + s.MapInfoID, + s.CellID, + s.Difficulty, + EnemyFleetName = !string.IsNullOrWhiteSpace(s.FleetName) ? s.FleetName : "敵艦隊名不明" + }) + .Distinct() + .OrderBy(r => r.MapAreaID) + .ThenBy(r => r.MapInfoID) + .ThenBy(r => r.CellID) + .ThenBy(r => r.Difficulty) + ) + { + sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", + record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); + } + + } + + return sb.ToString(); + } + + private void StripMenu_View_ShowAppearingArea_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship == null) + { + System.Media.SystemSounds.Exclamation.Play(); + return; + } + + string result = GetAppearingArea(ship.ShipID); + + if (string.IsNullOrEmpty(result)) + result = ship.NameWithClass + " の出現海域は不明です。"; + + MessageBox.Show(result, "出現海域検索", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + + + private void ShipBanner_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + + StripMenu_View_ShowShipGraphicViewer.PerformClick(); + } + } + + private void StripMenu_View_ShowShipGraphicViewer_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + { + + var pathlist = new LinkedList(); + pathlist.AddLast(SwfHelper.GetShipResourcePath(ship.ResourceName)); + + foreach (var rec in RecordManager.Instance.ShipParameter.Record.Values.Where(r => r.OriginalCostumeShipID == _shipID)) + { + string path = SwfHelper.GetShipResourcePath(rec.ResourceName); + if (path != null) + pathlist.AddLast(path); + } + + var arg = pathlist.Where(p => p != null).ToArray(); + if (arg.Length > 0) + { + new DialogShipGraphicViewer(arg).Show(Owner); + } + else + { + MessageBox.Show("画像リソースが存在しません。以下の手順を踏んでください。\r\n1. 設定→通信→通信内容を保存する 及び SWF を有効にする。\r\n2. キャッシュをクリアし、再読み込みする。\r\n3. 艦これ本体で当該艦を表示させる(図鑑画面を開くなど)。", "ビューア:画像リソース不足", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + else + { + MessageBox.Show("対象艦船を指定してください。", "ビューア:対象未指定", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + + + private void StripMenu_Edit_GoogleShipName_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship == null) + { + System.Media.SystemSounds.Exclamation.Play(); + return; + } + + try + { + + // google <艦船名> 艦これ + System.Diagnostics.Process.Start(@"https://www.google.co.jp/search?q=" + Uri.EscapeDataString(ship.NameWithClass) + "+%E8%89%A6%E3%81%93%E3%82%8C"); + + } + catch (Exception ex) + { + Utility.ErrorReporter.SendErrorReport(ex, "艦船名の Google 検索に失敗しました。"); + } + } + + } } From db7569c72228bb0d0906480a9995d25bacf6cfda Mon Sep 17 00:00:00 2001 From: Andante Date: Sat, 30 Dec 2017 07:22:09 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=E5=BE=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ElectronicObserver/Data/Battle/Detail/BattleDetail.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs b/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs index bc9757a96..7863191b1 100644 --- a/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs +++ b/ElectronicObserver/Data/Battle/Detail/BattleDetail.cs @@ -149,11 +149,9 @@ public override string ToString() StringBuilder builder = new StringBuilder(); - // 航空戦・支援攻撃時 AttackerIndex = BattleIndex.Invalid 、それで AttackerIndex.Side = BattleSides.FriendMain になる - // DefenderIndex.Side で判断すれば航空戦も正確に識別できるが表示が変になるので、最終的には AttackerIndex.Side で判断しだ - bool attackerIsFriend = AttackerIndex.Side == BattleSides.FriendMain || AttackerIndex.Side == BattleSides.FriendEscort; - - builder.AppendFormat(attackerIsFriend ? "{0} → {1}\r\n" : "{1} ← {0}\r\n", GetAttackerName(), GetDefenderName()); + // 航空戦・支援攻撃時 AttackerIndex = BattleIndex.Invalid 、それで AttackerIndex.Side = BattleSides.FriendMain になる + // DefenderIndex.Side で判断すれば航空戦も正確に識別できるが表示が変になるので、最終的には AttackerIndex.Side で判断した + builder.AppendFormat(AttackerIndex.IsFriend ? "{0} → {1}\r\n" : "{1} ← {0}\r\n", GetAttackerName(), GetDefenderName()); if (AttackType >= 0) From ad05749d2c1db91f39c1d66dd2f4e0542d36aab0 Mon Sep 17 00:00:00 2001 From: Andante Date: Sun, 31 Dec 2017 00:46:32 +0900 Subject: [PATCH 06/12] =?UTF-8?q?=E6=88=A6=E9=97=98=EF=BC=9A=E5=89=8D?= =?UTF-8?q?=E5=9B=9E=E3=81=AE=E6=88=A6=E9=97=98=E3=81=AE=E7=85=A7=E6=98=8E?= =?UTF-8?q?=E5=BC=BE=E3=82=A2=E3=82=A4=E3=82=B3=E3=83=B3=E3=81=8C=E6=B6=88?= =?UTF-8?q?=E3=81=88=E3=81=AA=E3=81=84=E3=81=93=E3=81=A8=E3=81=8C=E3=81=82?= =?UTF-8?q?=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 艦船図鑑:CSV出力において、ボイスフラグの出力が正しくない不具合を修正 --- ElectronicObserver/Data/Constants.cs | 12 ++++++------ ElectronicObserver/Window/FormBattle.cs | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ElectronicObserver/Data/Constants.cs b/ElectronicObserver/Data/Constants.cs index 3727f9ee9..3c0e66103 100644 --- a/ElectronicObserver/Data/Constants.cs +++ b/ElectronicObserver/Data/Constants.cs @@ -153,19 +153,19 @@ public static string GetVoiceFlag(int value) case 0: return "-"; case 1: - return "時報"; - case 2: return "放置"; + case 2: + return "時報"; case 3: - return "時報+放置"; + return "放置+時報"; case 4: return "特殊放置"; case 5: - return "時報+特殊放置"; - case 6: return "放置+特殊放置"; + case 6: + return "時報+特殊放置"; case 7: - return "時報+放置+特殊放置"; + return "放置+時報+特殊放置"; default: return "不明"; } diff --git a/ElectronicObserver/Window/FormBattle.cs b/ElectronicObserver/Window/FormBattle.cs index 3d1e6c84c..f4e1dc050 100644 --- a/ElectronicObserver/Window/FormBattle.cs +++ b/ElectronicObserver/Window/FormBattle.cs @@ -583,7 +583,10 @@ void SetShootdown(ImageLabel label, int stage, bool isFriend, bool needAppendInf label.ForeColor = Color.Red; else label.ForeColor = SystemColors.ControlText; - } + + label.ImageAlign = ContentAlignment.MiddleCenter; + label.ImageIndex = -1; + } void ClearAACutinLabel() { From 49bf7a642531e56640159ed9cf554e669f39ee09 Mon Sep 17 00:00:00 2001 From: Andante Date: Sun, 31 Dec 2017 00:52:05 +0900 Subject: [PATCH 07/12] =?UTF-8?q?VS=E3=81=AE=E8=A8=AD=E5=AE=9A=E3=81=8C?= =?UTF-8?q?=E5=A4=89=E3=82=8F=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE?= =?UTF-8?q?=E3=82=92=E5=BF=98=E3=82=8C=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ElectronicObserver/Data/Constants.cs | 2180 ++++++------ ElectronicObserver/Data/ShipData.cs | 2896 ++++++++-------- .../Window/Dialog/DialogAlbumMasterShip.cs | 2926 ++++++++--------- 3 files changed, 4001 insertions(+), 4001 deletions(-) diff --git a/ElectronicObserver/Data/Constants.cs b/ElectronicObserver/Data/Constants.cs index 3c0e66103..da2177955 100644 --- a/ElectronicObserver/Data/Constants.cs +++ b/ElectronicObserver/Data/Constants.cs @@ -8,1095 +8,1095 @@ namespace ElectronicObserver.Data { - public static class Constants - { - - #region 艦船・装備 - - /// - /// 艦船の速力を表す文字列を取得します。 - /// - public static string GetSpeed(int value) - { - switch (value) - { - case 0: - return "陸上"; - case 5: - return "低速"; - case 10: - return "高速"; - case 15: - return "高速+"; - case 20: - return "最速"; - default: - return "不明"; - } - } - - /// - /// 射程を表す文字列を取得します。 - /// - public static string GetRange(int value) - { - switch (value) - { - case 0: - return "無"; - case 1: - return "短"; - case 2: - return "中"; - case 3: - return "長"; - case 4: - return "超長"; - case 5: - return "超長+"; - default: - return "不明"; - } - } - - /// - /// 艦船のレアリティを表す文字列を取得します。 - /// - public static string GetShipRarity(int value) - { - switch (value) - { - case 0: - return "赤"; - case 1: - return "藍"; - case 2: - return "青"; - case 3: - return "水"; - case 4: - return "銀"; - case 5: - return "金"; - case 6: - return "虹"; - case 7: - return "輝虹"; - case 8: - return "桜虹"; - default: - return "不明"; - } - } - - /// - /// 装備のレアリティを表す文字列を取得します。 - /// - public static string GetEquipmentRarity(int value) - { - switch (value) - { - case 0: - return "コモン"; - case 1: - return "レア"; - case 2: - return "ホロ"; - case 3: - return "Sホロ"; - case 4: - return "SSホロ"; - case 5: - return "SSホロ'"; - case 6: - return "SSホロ+"; - default: - return "不明"; - } - } - - /// - /// 装備のレアリティの画像インデックスを取得します。 - /// - public static int GetEquipmentRarityID(int value) - { - switch (value) - { - case 0: - return 1; - case 1: - return 3; - case 2: - return 4; - case 3: - return 5; - case 4: - return 6; - case 5: - return 7; - case 6: - return 8; - default: - return 0; - } - } - - - /// - /// 艦船のボイス設定フラグを表す文字列を取得します。 - /// - public static string GetVoiceFlag(int value) - { - - switch (value) - { - case 0: - return "-"; - case 1: - return "放置"; - case 2: - return "時報"; - case 3: - return "放置+時報"; - case 4: - return "特殊放置"; - case 5: - return "放置+特殊放置"; - case 6: - return "時報+特殊放置"; - case 7: - return "放置+時報+特殊放置"; - default: - return "不明"; - } - } - - - /// - /// 艦船の損傷度合いを表す文字列を取得します。 - /// - /// 現在HP/最大HPで表される割合。 - /// 演習かどうか。 - /// 陸上基地かどうか。 - /// 退避中かどうか。 - /// - public static string GetDamageState(double hprate, bool isPractice = false, bool isLandBase = false, bool isEscaped = false) - { - - if (isEscaped) - return "退避"; - else if (hprate <= 0.0) - return isPractice ? "離脱" : (!isLandBase ? "撃沈" : "破壊"); - else if (hprate <= 0.25) - return !isLandBase ? "大破" : "損壊"; - else if (hprate <= 0.5) - return !isLandBase ? "中破" : "損害"; - else if (hprate <= 0.75) - return !isLandBase ? "小破" : "混乱"; - else if (hprate < 1.0) - return "健在"; - else - return "無傷"; - - } - - - /// - /// 基地航空隊の行動指示を表す文字列を取得します。 - /// - public static string GetBaseAirCorpsActionKind(int value) - { - switch (value) - { - case 0: - return "待機"; - case 1: - return "出撃"; - case 2: - return "防空"; - case 3: - return "退避"; - case 4: - return "休息"; - default: - return "不明"; - } - } - - - /// - /// 艦種略号を取得します。 - /// - public static string GetShipClassClassification(ShipTypes shiptype) - { - switch (shiptype) - { - case ShipTypes.Escort: - return "DE"; - case ShipTypes.Destroyer: - return "DD"; - case ShipTypes.LightCruiser: - return "CL"; - case ShipTypes.TorpedoCruiser: - return "CLT"; - case ShipTypes.HeavyCruiser: - return "CA"; - case ShipTypes.AviationCruiser: - return "CAV"; - case ShipTypes.LightAircraftCarrier: - return "CVL"; - case ShipTypes.Battlecruiser: - return "BC"; // ? FBB, CC? - case ShipTypes.Battleship: - return "BB"; - case ShipTypes.AviationBattleship: - return "BBV"; - case ShipTypes.AircraftCarrier: - return "CV"; - case ShipTypes.SuperDreadnoughts: - return "BB"; - case ShipTypes.Submarine: - return "SS"; - case ShipTypes.SubmarineAircraftCarrier: - return "SSV"; - case ShipTypes.Transport: - return "AP"; // ? AO? - case ShipTypes.SeaplaneTender: - return "AV"; - case ShipTypes.AmphibiousAssaultShip: - return "LHA"; - case ShipTypes.ArmoredAircraftCarrier: - return "CVB"; - case ShipTypes.RepairShip: - return "AR"; - case ShipTypes.SubmarineTender: - return "AS"; - case ShipTypes.TrainingCruiser: - return "CT"; - case ShipTypes.FleetOiler: - return "AO"; - default: - return "IX"; - } - } - - - /// - /// 艦型を表す文字列を取得します。 - /// - public static string GetShipClass(int id) - { - switch (id) - { - case 1: return "綾波型"; - case 2: return "伊勢型"; - case 3: return "加賀型"; - case 4: return "球磨型"; - case 5: return "暁型"; - case 6: return "金剛型"; - case 7: return "古鷹型"; - case 8: return "高雄型"; - case 9: return "最上型"; - case 10: return "初春型"; - case 11: return "祥鳳型"; - case 12: return "吹雪型"; - case 13: return "青葉型"; - case 14: return "赤城型"; - case 15: return "千歳型"; - case 16: return "川内型"; - case 17: return "蒼龍型"; - case 18: return "朝潮型"; - case 19: return "長門型"; - case 20: return "長良型"; - case 21: return "天龍型"; - case 22: return "島風型"; - case 23: return "白露型"; - case 24: return "飛鷹型"; - case 25: return "飛龍型"; - case 26: return "扶桑型"; - case 27: return "鳳翔型"; - case 28: return "睦月型"; - case 29: return "妙高型"; - case 30: return "陽炎型"; - case 31: return "利根型"; - case 32: return "龍驤型"; - case 33: return "翔鶴型"; - case 34: return "夕張型"; - case 35: return "海大VI型"; - case 36: return "巡潜乙型改二"; - case 37: return "大和型"; - case 38: return "夕雲型"; - case 39: return "巡潜乙型"; - case 40: return "巡潜3型"; - case 41: return "阿賀野型"; - case 42: return "「霧」"; - case 43: return "大鳳型"; - case 44: return "潜特型(伊400型潜水艦)"; - case 45: return "特種船丙型"; - case 46: return "三式潜航輸送艇"; - case 47: return "Bismarck級"; - case 48: return "Z1型"; - case 49: return "工作艦"; - case 50: return "大鯨型"; - case 51: return "龍鳳型"; - case 52: return "大淀型"; - case 53: return "雲龍型"; - case 54: return "秋月型"; - case 55: return "Admiral Hipper級"; - case 56: return "香取型"; - case 57: return "UボートIXC型/呂号潜水艦"; - case 58: return "V.Veneto級"; - case 59: return "秋津洲型"; - case 60: return "改風早型"; - case 61: return "Maestrale級"; - case 62: return "瑞穂型"; - case 63: return "Graf Zeppelin級"; - case 64: return "Zara級"; - case 65: return "Iowa級"; - case 66: return "神風型"; - case 67: return "Queen Elizabeth級"; - case 68: return "Aquila級"; - case 69: return "Lexington級"; - case 70: return "C.Teste級"; - case 71: return "巡潜甲型改二"; - case 72: return "神威型"; - case 73: return "Гангут級"; - case 74: return "占守型"; - case 75: return "春日丸級"; - case 76: return "大鷹型"; - case 77: return "択捉型"; - case 78: return "Ark Royal級"; - case 79: return "Richelieu級"; - case 80: return "Guglielmo Marconi級"; - default: return "不明"; - } - } - - #endregion - - - #region 出撃 - - /// - /// マップ上のセルでのイベントを表す文字列を取得します。 - /// - public static string GetMapEventID(int value) - { - - switch (value) - { - - case 0: - return "初期位置"; - case 1: - return "なし"; - case 2: - return "資源"; - case 3: - return "渦潮"; - case 4: - return "通常戦闘"; - case 5: - return "ボス戦闘"; - case 6: - return "気のせいだった"; - case 7: - return "航空戦"; - case 8: - return "船団護衛成功"; - case 9: - return "揚陸地点"; - default: - return "不明"; - } - } - - /// - /// マップ上のセルでのイベント種別を表す文字列を取得します。 - /// - public static string GetMapEventKind(int value) - { - - switch (value) - { - case 0: - return "非戦闘"; - case 1: - return "昼夜戦"; - case 2: - return "夜戦"; - case 3: - return "夜昼戦"; // 対通常? - case 4: - return "航空戦"; - case 5: - return "敵連合"; - case 6: - return "空襲戦"; - case 7: - return "夜昼戦"; // 対連合 - default: - return "不明"; - } - } - - - /// - /// 海域難易度を表す文字列を取得します。 - /// - public static string GetDifficulty(int value) - { - - switch (value) - { - case -1: - return "なし"; - case 0: - return "未選択"; - case 1: - return "丙"; - case 2: - return "乙"; - case 3: - return "甲"; - default: - return "不明"; - } - } - - /// - /// 海域難易度を表す数値を取得します。 - /// - public static int GetDifficulty(string value) - { - - switch (value) - { - case "未選択": - return 0; - case "丙": - return 1; - case "乙": - return 2; - case "甲": - return 3; - default: - return -1; - } - - } - - /// - /// 空襲被害の状態を表す文字列を取得します。 - /// - public static string GetAirRaidDamage(int value) - { - switch (value) - { - case 1: - return "資源に損害"; - case 2: - return "資源・航空隊に損害"; - case 3: - return "航空隊に損害"; - case 4: - return "損害なし"; - default: - return "発生せず"; - } - } - - /// - /// 空襲被害の状態を表す文字列を取得します。(短縮版) - /// - public static string GetAirRaidDamageShort(int value) - { - switch (value) - { - case 1: - return "資源損害"; - case 2: - return "資源・航空"; - case 3: - return "航空隊損害"; - case 4: - return "損害なし"; - default: - return "-"; - } - } - - - #endregion - - - #region 戦闘 - - /// - /// 陣形を表す文字列を取得します。 - /// - public static string GetFormation(int id) - { - switch (id) - { - case 1: - return "単縦陣"; - case 2: - return "複縦陣"; - case 3: - return "輪形陣"; - case 4: - return "梯形陣"; - case 5: - return "単横陣"; - case 6: - return "警戒陣"; - case 11: - return "第一警戒航行序列"; - case 12: - return "第二警戒航行序列"; - case 13: - return "第三警戒航行序列"; - case 14: - return "第四警戒航行序列"; - default: - return "不明"; - } - } - - /// - /// 陣形を表す数値を取得します。 - /// - public static int GetFormation(string value) - { - switch (value) - { - case "単縦陣": - return 1; - case "複縦陣": - return 2; - case "輪形陣": - return 3; - case "梯形陣": - return 4; - case "単横陣": - return 5; - case "警戒陣": - return 6; - case "第一警戒航行序列": - return 11; - case "第二警戒航行序列": - return 12; - case "第三警戒航行序列": - return 13; - case "第四警戒航行序列": - return 14; - default: - return -1; - } - } - - /// - /// 陣形を表す文字列(短縮版)を取得します。 - /// - public static string GetFormationShort(int id) - { - switch (id) - { - case 1: - return "単縦陣"; - case 2: - return "複縦陣"; - case 3: - return "輪形陣"; - case 4: - return "梯形陣"; - case 5: - return "単横陣"; - case 6: - return "警戒陣"; - case 11: - return "第一警戒"; - case 12: - return "第二警戒"; - case 13: - return "第三警戒"; - case 14: - return "第四警戒"; - default: - return "不明"; - } - } - - /// - /// 交戦形態を表す文字列を取得します。 - /// - public static string GetEngagementForm(int id) - { - switch (id) - { - case 1: - return "同航戦"; - case 2: - return "反航戦"; - case 3: - return "T字有利"; - case 4: - return "T字不利"; - default: - return "不明"; - } - } - - /// - /// 索敵結果を表す文字列を取得します。 - /// - public static string GetSearchingResult(int id) - { - switch (id) - { - case 1: - return "成功"; - case 2: - return "成功(未帰還有)"; - case 3: - return "未帰還"; - case 4: - return "失敗"; - case 5: - return "成功(非索敵機)"; - case 6: - return "失敗(非索敵機)"; - default: - return "不明"; - } - } - - /// - /// 索敵結果を表す文字列(短縮版)を取得します。 - /// - public static string GetSearchingResultShort(int id) - { - switch (id) - { - case 1: - return "成功"; - case 2: - return "成功△"; - case 3: - return "未帰還"; - case 4: - return "失敗"; - case 5: - return "成功"; - case 6: - return "失敗"; - default: - return "不明"; - } - } - - /// - /// 制空戦の結果を表す文字列を取得します。 - /// - public static string GetAirSuperiority(int id) - { - switch (id) - { - case 0: - return "航空均衡"; - case 1: - return "制空権確保"; - case 2: - return "航空優勢"; - case 3: - return "航空劣勢"; - case 4: - return "制空権喪失"; - default: - return "不明"; - } - } - - - - /// - /// 昼戦攻撃種別を表す文字列を取得します。 - /// - public static string GetDayAttackKind(DayAttackKind id) - { - switch (id) - { - case DayAttackKind.NormalAttack: - return "通常攻撃"; - case DayAttackKind.Laser: - return "レーザー攻撃"; - case DayAttackKind.DoubleShelling: - return "連続射撃"; - case DayAttackKind.CutinMainSub: - return "カットイン(主砲/副砲)"; - case DayAttackKind.CutinMainRadar: - return "カットイン(主砲/電探)"; - case DayAttackKind.CutinMainAP: - return "カットイン(主砲/徹甲)"; - case DayAttackKind.CutinMainMain: - return "カットイン(主砲/主砲)"; - case DayAttackKind.CutinAirAttack: - return "空母カットイン"; - case DayAttackKind.Shelling: - return "砲撃"; - case DayAttackKind.AirAttack: - return "空撃"; - case DayAttackKind.DepthCharge: - return "爆雷攻撃"; - case DayAttackKind.Torpedo: - return "雷撃"; - case DayAttackKind.Rocket: - return "ロケット砲撃"; - case DayAttackKind.LandingDaihatsu: - return "揚陸攻撃(大発動艇)"; - case DayAttackKind.LandingTokuDaihatsu: - return "揚陸攻撃(特大発動艇)"; - case DayAttackKind.LandingDaihatsuTank: - return "揚陸攻撃(大発戦車)"; - case DayAttackKind.LandingAmphibious: - return "揚陸攻撃(内火艇)"; - case DayAttackKind.LandingTokuDaihatsuTank: - return "揚陸攻撃(特大発戦車)"; - default: - return "不明"; - } - } - - - /// - /// 夜戦攻撃種別を表す文字列を取得します。 - /// - public static string GetNightAttackKind(NightAttackKind id) - { - switch (id) - { - case NightAttackKind.NormalAttack: - return "通常攻撃"; - case NightAttackKind.DoubleShelling: - return "連続射撃"; - case NightAttackKind.CutinMainTorpedo: - return "カットイン(主砲/魚雷)"; - case NightAttackKind.CutinTorpedoTorpedo: - return "カットイン(魚雷x2)"; - case NightAttackKind.CutinMainSub: - return "カットイン(主砲x2/副砲)"; - case NightAttackKind.CutinMainMain: - return "カットイン(主砲x3)"; - case NightAttackKind.CutinAirAttack: - return "空母カットイン"; - case NightAttackKind.CutinTorpedoRadar: - return "駆逐カットイン(主砲/魚雷/電探)"; - case NightAttackKind.CutinTorpedoPicket: - return "駆逐カットイン(魚雷/見張員/電探)"; - case NightAttackKind.Shelling: - return "砲撃"; - case NightAttackKind.AirAttack: - return "空撃"; - case NightAttackKind.DepthCharge: - return "爆雷攻撃"; - case NightAttackKind.Torpedo: - return "雷撃"; - case NightAttackKind.Rocket: - return "ロケット砲撃"; - case NightAttackKind.LandingDaihatsu: - return "揚陸攻撃(大発動艇)"; - case NightAttackKind.LandingTokuDaihatsu: - return "揚陸攻撃(特大発動艇)"; - case NightAttackKind.LandingDaihatsuTank: - return "揚陸攻撃(大発戦車)"; - case NightAttackKind.LandingAmphibious: - return "揚陸攻撃(内火艇)"; - case NightAttackKind.LandingTokuDaihatsuTank: - return "揚陸攻撃(特大発戦車)"; - default: - return "不明"; - } - } - - - /// - /// 対空カットイン種別を表す文字列を取得します。 - /// - public static string GetAACutinKind(int id) - { - switch (id) - { - case 0: - return "なし"; - case 1: - return "高角砲x2/電探(秋月)"; - case 2: - return "高角砲/電探(秋月)"; - case 3: - return "高角砲x2(秋月)"; - case 4: - return "大口径主砲/三式弾/高射装置/電探"; - case 5: - return "高角砲+高射装置x2/電探"; - case 6: - return "大口径主砲/三式弾/高射装置"; - case 7: - return "高角砲/高射装置/電探"; - case 8: - return "高角砲+高射装置/電探"; - case 9: - return "高角砲/高射装置"; - case 10: - return "高角砲/集中機銃/電探(摩耶)"; - case 11: - return "高角砲/集中機銃(摩耶)"; - case 12: - return "集中機銃/機銃/電探"; - case 14: - return "高角砲/機銃/電探(五十鈴)"; - case 15: - return "高角砲/機銃(五十鈴)"; - case 16: - return "高角砲/機銃/電探(霞)"; - case 17: - return "高角砲/機銃(霞)"; - case 18: - return "集中機銃(皐月)"; - case 19: - return "高角砲(非高射装置)/集中機銃(鬼怒)"; - case 20: - return "集中機銃(鬼怒)"; - case 21: - return "高角砲/電探(由良)"; - case 22: - return "集中機銃(文月)"; - case 23: - return "機銃(非集中)(UIT-25)"; - default: - return "不明"; - } - } - - - /// - /// 勝利ランクを表すIDを取得します。 - /// - public static int GetWinRank(string rank) - { - switch (rank.ToUpper()) - { - case "E": - return 1; - case "D": - return 2; - case "C": - return 3; - case "B": - return 4; - case "A": - return 5; - case "S": - return 6; - case "SS": - return 7; - default: - return 0; - } - } - - /// - /// 勝利ランクを表す文字列を取得します。 - /// - public static string GetWinRank(int rank) - { - switch (rank) - { - case 1: - return "E"; - case 2: - return "D"; - case 3: - return "C"; - case 4: - return "B"; - case 5: - return "A"; - case 6: - return "S"; - case 7: - return "SS"; - default: - return "不明"; - } - } - - #endregion - - - #region その他 - - /// - /// 資源の名前を取得します。 - /// - /// 資源のID。 - /// 資源の名前。 - public static string GetMaterialName(int materialID) - { - - switch (materialID) - { - case 1: - return "燃料"; - case 2: - return "弾薬"; - case 3: - return "鋼材"; - case 4: - return "ボーキサイト"; - case 5: - return "高速建造材"; - case 6: - return "高速修復材"; - case 7: - return "開発資材"; - case 8: - return "改修資材"; - default: - return "不明"; - } - } - - - /// - /// 階級を表す文字列を取得します。 - /// - public static string GetAdmiralRank(int id) - { - switch (id) - { - case 1: - return "元帥"; - case 2: - return "大将"; - case 3: - return "中将"; - case 4: - return "少将"; - case 5: - return "大佐"; - case 6: - return "中佐"; - case 7: - return "新米中佐"; - case 8: - return "少佐"; - case 9: - return "中堅少佐"; - case 10: - return "新米少佐"; - default: - return "提督"; - } - } - - - /// - /// 任務の発生タイプを表す文字列を取得します。 - /// - public static string GetQuestType(int id) - { - switch (id) - { - case 1: //デイリー - return "日"; - case 2: //ウィークリー - return "週"; - case 3: //マンスリー - return "月"; - case 4: //単発 - return "単"; - case 5: //その他(輸送5/空母3) - return "他"; - default: - return "?"; - } - - } - - - /// - /// 任務のカテゴリを表す文字列を取得します。 - /// - public static string GetQuestCategory(int id) - { - switch (id) - { - case 1: - return "編成"; - case 2: - return "出撃"; - case 3: - return "演習"; - case 4: - return "遠征"; - case 5: - return "補給"; //入渠も含むが、文字数の関係 - case 6: - return "工廠"; - case 7: - return "改装"; - case 8: - return "出撃"; - case 9: - return "他"; - default: - return "不明"; - } - } - - - /// - /// 遠征の結果を表す文字列を取得します。 - /// - public static string GetExpeditionResult(int value) - { - switch (value) - { - case 0: - return "失敗"; - case 1: - return "成功"; - case 2: - return "大成功"; - default: - return "不明"; - } - } - - - /// - /// 連合艦隊の編成名を表す文字列を取得します。 - /// - public static string GetCombinedFleet(int value) - { - switch (value) - { - case 0: - return "通常艦隊"; - case 1: - return "機動部隊"; - case 2: - return "水上部隊"; - case 3: - return "輸送部隊"; - default: - return "不明"; - } - } - - #endregion - - } + public static class Constants + { + + #region 艦船・装備 + + /// + /// 艦船の速力を表す文字列を取得します。 + /// + public static string GetSpeed(int value) + { + switch (value) + { + case 0: + return "陸上"; + case 5: + return "低速"; + case 10: + return "高速"; + case 15: + return "高速+"; + case 20: + return "最速"; + default: + return "不明"; + } + } + + /// + /// 射程を表す文字列を取得します。 + /// + public static string GetRange(int value) + { + switch (value) + { + case 0: + return "無"; + case 1: + return "短"; + case 2: + return "中"; + case 3: + return "長"; + case 4: + return "超長"; + case 5: + return "超長+"; + default: + return "不明"; + } + } + + /// + /// 艦船のレアリティを表す文字列を取得します。 + /// + public static string GetShipRarity(int value) + { + switch (value) + { + case 0: + return "赤"; + case 1: + return "藍"; + case 2: + return "青"; + case 3: + return "水"; + case 4: + return "銀"; + case 5: + return "金"; + case 6: + return "虹"; + case 7: + return "輝虹"; + case 8: + return "桜虹"; + default: + return "不明"; + } + } + + /// + /// 装備のレアリティを表す文字列を取得します。 + /// + public static string GetEquipmentRarity(int value) + { + switch (value) + { + case 0: + return "コモン"; + case 1: + return "レア"; + case 2: + return "ホロ"; + case 3: + return "Sホロ"; + case 4: + return "SSホロ"; + case 5: + return "SSホロ'"; + case 6: + return "SSホロ+"; + default: + return "不明"; + } + } + + /// + /// 装備のレアリティの画像インデックスを取得します。 + /// + public static int GetEquipmentRarityID(int value) + { + switch (value) + { + case 0: + return 1; + case 1: + return 3; + case 2: + return 4; + case 3: + return 5; + case 4: + return 6; + case 5: + return 7; + case 6: + return 8; + default: + return 0; + } + } + + + /// + /// 艦船のボイス設定フラグを表す文字列を取得します。 + /// + public static string GetVoiceFlag(int value) + { + + switch (value) + { + case 0: + return "-"; + case 1: + return "放置"; + case 2: + return "時報"; + case 3: + return "放置+時報"; + case 4: + return "特殊放置"; + case 5: + return "放置+特殊放置"; + case 6: + return "時報+特殊放置"; + case 7: + return "放置+時報+特殊放置"; + default: + return "不明"; + } + } + + + /// + /// 艦船の損傷度合いを表す文字列を取得します。 + /// + /// 現在HP/最大HPで表される割合。 + /// 演習かどうか。 + /// 陸上基地かどうか。 + /// 退避中かどうか。 + /// + public static string GetDamageState(double hprate, bool isPractice = false, bool isLandBase = false, bool isEscaped = false) + { + + if (isEscaped) + return "退避"; + else if (hprate <= 0.0) + return isPractice ? "離脱" : (!isLandBase ? "撃沈" : "破壊"); + else if (hprate <= 0.25) + return !isLandBase ? "大破" : "損壊"; + else if (hprate <= 0.5) + return !isLandBase ? "中破" : "損害"; + else if (hprate <= 0.75) + return !isLandBase ? "小破" : "混乱"; + else if (hprate < 1.0) + return "健在"; + else + return "無傷"; + + } + + + /// + /// 基地航空隊の行動指示を表す文字列を取得します。 + /// + public static string GetBaseAirCorpsActionKind(int value) + { + switch (value) + { + case 0: + return "待機"; + case 1: + return "出撃"; + case 2: + return "防空"; + case 3: + return "退避"; + case 4: + return "休息"; + default: + return "不明"; + } + } + + + /// + /// 艦種略号を取得します。 + /// + public static string GetShipClassClassification(ShipTypes shiptype) + { + switch (shiptype) + { + case ShipTypes.Escort: + return "DE"; + case ShipTypes.Destroyer: + return "DD"; + case ShipTypes.LightCruiser: + return "CL"; + case ShipTypes.TorpedoCruiser: + return "CLT"; + case ShipTypes.HeavyCruiser: + return "CA"; + case ShipTypes.AviationCruiser: + return "CAV"; + case ShipTypes.LightAircraftCarrier: + return "CVL"; + case ShipTypes.Battlecruiser: + return "BC"; // ? FBB, CC? + case ShipTypes.Battleship: + return "BB"; + case ShipTypes.AviationBattleship: + return "BBV"; + case ShipTypes.AircraftCarrier: + return "CV"; + case ShipTypes.SuperDreadnoughts: + return "BB"; + case ShipTypes.Submarine: + return "SS"; + case ShipTypes.SubmarineAircraftCarrier: + return "SSV"; + case ShipTypes.Transport: + return "AP"; // ? AO? + case ShipTypes.SeaplaneTender: + return "AV"; + case ShipTypes.AmphibiousAssaultShip: + return "LHA"; + case ShipTypes.ArmoredAircraftCarrier: + return "CVB"; + case ShipTypes.RepairShip: + return "AR"; + case ShipTypes.SubmarineTender: + return "AS"; + case ShipTypes.TrainingCruiser: + return "CT"; + case ShipTypes.FleetOiler: + return "AO"; + default: + return "IX"; + } + } + + + /// + /// 艦型を表す文字列を取得します。 + /// + public static string GetShipClass(int id) + { + switch (id) + { + case 1: return "綾波型"; + case 2: return "伊勢型"; + case 3: return "加賀型"; + case 4: return "球磨型"; + case 5: return "暁型"; + case 6: return "金剛型"; + case 7: return "古鷹型"; + case 8: return "高雄型"; + case 9: return "最上型"; + case 10: return "初春型"; + case 11: return "祥鳳型"; + case 12: return "吹雪型"; + case 13: return "青葉型"; + case 14: return "赤城型"; + case 15: return "千歳型"; + case 16: return "川内型"; + case 17: return "蒼龍型"; + case 18: return "朝潮型"; + case 19: return "長門型"; + case 20: return "長良型"; + case 21: return "天龍型"; + case 22: return "島風型"; + case 23: return "白露型"; + case 24: return "飛鷹型"; + case 25: return "飛龍型"; + case 26: return "扶桑型"; + case 27: return "鳳翔型"; + case 28: return "睦月型"; + case 29: return "妙高型"; + case 30: return "陽炎型"; + case 31: return "利根型"; + case 32: return "龍驤型"; + case 33: return "翔鶴型"; + case 34: return "夕張型"; + case 35: return "海大VI型"; + case 36: return "巡潜乙型改二"; + case 37: return "大和型"; + case 38: return "夕雲型"; + case 39: return "巡潜乙型"; + case 40: return "巡潜3型"; + case 41: return "阿賀野型"; + case 42: return "「霧」"; + case 43: return "大鳳型"; + case 44: return "潜特型(伊400型潜水艦)"; + case 45: return "特種船丙型"; + case 46: return "三式潜航輸送艇"; + case 47: return "Bismarck級"; + case 48: return "Z1型"; + case 49: return "工作艦"; + case 50: return "大鯨型"; + case 51: return "龍鳳型"; + case 52: return "大淀型"; + case 53: return "雲龍型"; + case 54: return "秋月型"; + case 55: return "Admiral Hipper級"; + case 56: return "香取型"; + case 57: return "UボートIXC型/呂号潜水艦"; + case 58: return "V.Veneto級"; + case 59: return "秋津洲型"; + case 60: return "改風早型"; + case 61: return "Maestrale級"; + case 62: return "瑞穂型"; + case 63: return "Graf Zeppelin級"; + case 64: return "Zara級"; + case 65: return "Iowa級"; + case 66: return "神風型"; + case 67: return "Queen Elizabeth級"; + case 68: return "Aquila級"; + case 69: return "Lexington級"; + case 70: return "C.Teste級"; + case 71: return "巡潜甲型改二"; + case 72: return "神威型"; + case 73: return "Гангут級"; + case 74: return "占守型"; + case 75: return "春日丸級"; + case 76: return "大鷹型"; + case 77: return "択捉型"; + case 78: return "Ark Royal級"; + case 79: return "Richelieu級"; + case 80: return "Guglielmo Marconi級"; + default: return "不明"; + } + } + + #endregion + + + #region 出撃 + + /// + /// マップ上のセルでのイベントを表す文字列を取得します。 + /// + public static string GetMapEventID(int value) + { + + switch (value) + { + + case 0: + return "初期位置"; + case 1: + return "なし"; + case 2: + return "資源"; + case 3: + return "渦潮"; + case 4: + return "通常戦闘"; + case 5: + return "ボス戦闘"; + case 6: + return "気のせいだった"; + case 7: + return "航空戦"; + case 8: + return "船団護衛成功"; + case 9: + return "揚陸地点"; + default: + return "不明"; + } + } + + /// + /// マップ上のセルでのイベント種別を表す文字列を取得します。 + /// + public static string GetMapEventKind(int value) + { + + switch (value) + { + case 0: + return "非戦闘"; + case 1: + return "昼夜戦"; + case 2: + return "夜戦"; + case 3: + return "夜昼戦"; // 対通常? + case 4: + return "航空戦"; + case 5: + return "敵連合"; + case 6: + return "空襲戦"; + case 7: + return "夜昼戦"; // 対連合 + default: + return "不明"; + } + } + + + /// + /// 海域難易度を表す文字列を取得します。 + /// + public static string GetDifficulty(int value) + { + + switch (value) + { + case -1: + return "なし"; + case 0: + return "未選択"; + case 1: + return "丙"; + case 2: + return "乙"; + case 3: + return "甲"; + default: + return "不明"; + } + } + + /// + /// 海域難易度を表す数値を取得します。 + /// + public static int GetDifficulty(string value) + { + + switch (value) + { + case "未選択": + return 0; + case "丙": + return 1; + case "乙": + return 2; + case "甲": + return 3; + default: + return -1; + } + + } + + /// + /// 空襲被害の状態を表す文字列を取得します。 + /// + public static string GetAirRaidDamage(int value) + { + switch (value) + { + case 1: + return "資源に損害"; + case 2: + return "資源・航空隊に損害"; + case 3: + return "航空隊に損害"; + case 4: + return "損害なし"; + default: + return "発生せず"; + } + } + + /// + /// 空襲被害の状態を表す文字列を取得します。(短縮版) + /// + public static string GetAirRaidDamageShort(int value) + { + switch (value) + { + case 1: + return "資源損害"; + case 2: + return "資源・航空"; + case 3: + return "航空隊損害"; + case 4: + return "損害なし"; + default: + return "-"; + } + } + + + #endregion + + + #region 戦闘 + + /// + /// 陣形を表す文字列を取得します。 + /// + public static string GetFormation(int id) + { + switch (id) + { + case 1: + return "単縦陣"; + case 2: + return "複縦陣"; + case 3: + return "輪形陣"; + case 4: + return "梯形陣"; + case 5: + return "単横陣"; + case 6: + return "警戒陣"; + case 11: + return "第一警戒航行序列"; + case 12: + return "第二警戒航行序列"; + case 13: + return "第三警戒航行序列"; + case 14: + return "第四警戒航行序列"; + default: + return "不明"; + } + } + + /// + /// 陣形を表す数値を取得します。 + /// + public static int GetFormation(string value) + { + switch (value) + { + case "単縦陣": + return 1; + case "複縦陣": + return 2; + case "輪形陣": + return 3; + case "梯形陣": + return 4; + case "単横陣": + return 5; + case "警戒陣": + return 6; + case "第一警戒航行序列": + return 11; + case "第二警戒航行序列": + return 12; + case "第三警戒航行序列": + return 13; + case "第四警戒航行序列": + return 14; + default: + return -1; + } + } + + /// + /// 陣形を表す文字列(短縮版)を取得します。 + /// + public static string GetFormationShort(int id) + { + switch (id) + { + case 1: + return "単縦陣"; + case 2: + return "複縦陣"; + case 3: + return "輪形陣"; + case 4: + return "梯形陣"; + case 5: + return "単横陣"; + case 6: + return "警戒陣"; + case 11: + return "第一警戒"; + case 12: + return "第二警戒"; + case 13: + return "第三警戒"; + case 14: + return "第四警戒"; + default: + return "不明"; + } + } + + /// + /// 交戦形態を表す文字列を取得します。 + /// + public static string GetEngagementForm(int id) + { + switch (id) + { + case 1: + return "同航戦"; + case 2: + return "反航戦"; + case 3: + return "T字有利"; + case 4: + return "T字不利"; + default: + return "不明"; + } + } + + /// + /// 索敵結果を表す文字列を取得します。 + /// + public static string GetSearchingResult(int id) + { + switch (id) + { + case 1: + return "成功"; + case 2: + return "成功(未帰還有)"; + case 3: + return "未帰還"; + case 4: + return "失敗"; + case 5: + return "成功(非索敵機)"; + case 6: + return "失敗(非索敵機)"; + default: + return "不明"; + } + } + + /// + /// 索敵結果を表す文字列(短縮版)を取得します。 + /// + public static string GetSearchingResultShort(int id) + { + switch (id) + { + case 1: + return "成功"; + case 2: + return "成功△"; + case 3: + return "未帰還"; + case 4: + return "失敗"; + case 5: + return "成功"; + case 6: + return "失敗"; + default: + return "不明"; + } + } + + /// + /// 制空戦の結果を表す文字列を取得します。 + /// + public static string GetAirSuperiority(int id) + { + switch (id) + { + case 0: + return "航空均衡"; + case 1: + return "制空権確保"; + case 2: + return "航空優勢"; + case 3: + return "航空劣勢"; + case 4: + return "制空権喪失"; + default: + return "不明"; + } + } + + + + /// + /// 昼戦攻撃種別を表す文字列を取得します。 + /// + public static string GetDayAttackKind(DayAttackKind id) + { + switch (id) + { + case DayAttackKind.NormalAttack: + return "通常攻撃"; + case DayAttackKind.Laser: + return "レーザー攻撃"; + case DayAttackKind.DoubleShelling: + return "連続射撃"; + case DayAttackKind.CutinMainSub: + return "カットイン(主砲/副砲)"; + case DayAttackKind.CutinMainRadar: + return "カットイン(主砲/電探)"; + case DayAttackKind.CutinMainAP: + return "カットイン(主砲/徹甲)"; + case DayAttackKind.CutinMainMain: + return "カットイン(主砲/主砲)"; + case DayAttackKind.CutinAirAttack: + return "空母カットイン"; + case DayAttackKind.Shelling: + return "砲撃"; + case DayAttackKind.AirAttack: + return "空撃"; + case DayAttackKind.DepthCharge: + return "爆雷攻撃"; + case DayAttackKind.Torpedo: + return "雷撃"; + case DayAttackKind.Rocket: + return "ロケット砲撃"; + case DayAttackKind.LandingDaihatsu: + return "揚陸攻撃(大発動艇)"; + case DayAttackKind.LandingTokuDaihatsu: + return "揚陸攻撃(特大発動艇)"; + case DayAttackKind.LandingDaihatsuTank: + return "揚陸攻撃(大発戦車)"; + case DayAttackKind.LandingAmphibious: + return "揚陸攻撃(内火艇)"; + case DayAttackKind.LandingTokuDaihatsuTank: + return "揚陸攻撃(特大発戦車)"; + default: + return "不明"; + } + } + + + /// + /// 夜戦攻撃種別を表す文字列を取得します。 + /// + public static string GetNightAttackKind(NightAttackKind id) + { + switch (id) + { + case NightAttackKind.NormalAttack: + return "通常攻撃"; + case NightAttackKind.DoubleShelling: + return "連続射撃"; + case NightAttackKind.CutinMainTorpedo: + return "カットイン(主砲/魚雷)"; + case NightAttackKind.CutinTorpedoTorpedo: + return "カットイン(魚雷x2)"; + case NightAttackKind.CutinMainSub: + return "カットイン(主砲x2/副砲)"; + case NightAttackKind.CutinMainMain: + return "カットイン(主砲x3)"; + case NightAttackKind.CutinAirAttack: + return "空母カットイン"; + case NightAttackKind.CutinTorpedoRadar: + return "駆逐カットイン(主砲/魚雷/電探)"; + case NightAttackKind.CutinTorpedoPicket: + return "駆逐カットイン(魚雷/見張員/電探)"; + case NightAttackKind.Shelling: + return "砲撃"; + case NightAttackKind.AirAttack: + return "空撃"; + case NightAttackKind.DepthCharge: + return "爆雷攻撃"; + case NightAttackKind.Torpedo: + return "雷撃"; + case NightAttackKind.Rocket: + return "ロケット砲撃"; + case NightAttackKind.LandingDaihatsu: + return "揚陸攻撃(大発動艇)"; + case NightAttackKind.LandingTokuDaihatsu: + return "揚陸攻撃(特大発動艇)"; + case NightAttackKind.LandingDaihatsuTank: + return "揚陸攻撃(大発戦車)"; + case NightAttackKind.LandingAmphibious: + return "揚陸攻撃(内火艇)"; + case NightAttackKind.LandingTokuDaihatsuTank: + return "揚陸攻撃(特大発戦車)"; + default: + return "不明"; + } + } + + + /// + /// 対空カットイン種別を表す文字列を取得します。 + /// + public static string GetAACutinKind(int id) + { + switch (id) + { + case 0: + return "なし"; + case 1: + return "高角砲x2/電探(秋月)"; + case 2: + return "高角砲/電探(秋月)"; + case 3: + return "高角砲x2(秋月)"; + case 4: + return "大口径主砲/三式弾/高射装置/電探"; + case 5: + return "高角砲+高射装置x2/電探"; + case 6: + return "大口径主砲/三式弾/高射装置"; + case 7: + return "高角砲/高射装置/電探"; + case 8: + return "高角砲+高射装置/電探"; + case 9: + return "高角砲/高射装置"; + case 10: + return "高角砲/集中機銃/電探(摩耶)"; + case 11: + return "高角砲/集中機銃(摩耶)"; + case 12: + return "集中機銃/機銃/電探"; + case 14: + return "高角砲/機銃/電探(五十鈴)"; + case 15: + return "高角砲/機銃(五十鈴)"; + case 16: + return "高角砲/機銃/電探(霞)"; + case 17: + return "高角砲/機銃(霞)"; + case 18: + return "集中機銃(皐月)"; + case 19: + return "高角砲(非高射装置)/集中機銃(鬼怒)"; + case 20: + return "集中機銃(鬼怒)"; + case 21: + return "高角砲/電探(由良)"; + case 22: + return "集中機銃(文月)"; + case 23: + return "機銃(非集中)(UIT-25)"; + default: + return "不明"; + } + } + + + /// + /// 勝利ランクを表すIDを取得します。 + /// + public static int GetWinRank(string rank) + { + switch (rank.ToUpper()) + { + case "E": + return 1; + case "D": + return 2; + case "C": + return 3; + case "B": + return 4; + case "A": + return 5; + case "S": + return 6; + case "SS": + return 7; + default: + return 0; + } + } + + /// + /// 勝利ランクを表す文字列を取得します。 + /// + public static string GetWinRank(int rank) + { + switch (rank) + { + case 1: + return "E"; + case 2: + return "D"; + case 3: + return "C"; + case 4: + return "B"; + case 5: + return "A"; + case 6: + return "S"; + case 7: + return "SS"; + default: + return "不明"; + } + } + + #endregion + + + #region その他 + + /// + /// 資源の名前を取得します。 + /// + /// 資源のID。 + /// 資源の名前。 + public static string GetMaterialName(int materialID) + { + + switch (materialID) + { + case 1: + return "燃料"; + case 2: + return "弾薬"; + case 3: + return "鋼材"; + case 4: + return "ボーキサイト"; + case 5: + return "高速建造材"; + case 6: + return "高速修復材"; + case 7: + return "開発資材"; + case 8: + return "改修資材"; + default: + return "不明"; + } + } + + + /// + /// 階級を表す文字列を取得します。 + /// + public static string GetAdmiralRank(int id) + { + switch (id) + { + case 1: + return "元帥"; + case 2: + return "大将"; + case 3: + return "中将"; + case 4: + return "少将"; + case 5: + return "大佐"; + case 6: + return "中佐"; + case 7: + return "新米中佐"; + case 8: + return "少佐"; + case 9: + return "中堅少佐"; + case 10: + return "新米少佐"; + default: + return "提督"; + } + } + + + /// + /// 任務の発生タイプを表す文字列を取得します。 + /// + public static string GetQuestType(int id) + { + switch (id) + { + case 1: //デイリー + return "日"; + case 2: //ウィークリー + return "週"; + case 3: //マンスリー + return "月"; + case 4: //単発 + return "単"; + case 5: //その他(輸送5/空母3) + return "他"; + default: + return "?"; + } + + } + + + /// + /// 任務のカテゴリを表す文字列を取得します。 + /// + public static string GetQuestCategory(int id) + { + switch (id) + { + case 1: + return "編成"; + case 2: + return "出撃"; + case 3: + return "演習"; + case 4: + return "遠征"; + case 5: + return "補給"; //入渠も含むが、文字数の関係 + case 6: + return "工廠"; + case 7: + return "改装"; + case 8: + return "出撃"; + case 9: + return "他"; + default: + return "不明"; + } + } + + + /// + /// 遠征の結果を表す文字列を取得します。 + /// + public static string GetExpeditionResult(int value) + { + switch (value) + { + case 0: + return "失敗"; + case 1: + return "成功"; + case 2: + return "大成功"; + default: + return "不明"; + } + } + + + /// + /// 連合艦隊の編成名を表す文字列を取得します。 + /// + public static string GetCombinedFleet(int value) + { + switch (value) + { + case 0: + return "通常艦隊"; + case 1: + return "機動部隊"; + case 2: + return "水上部隊"; + case 3: + return "輸送部隊"; + default: + return "不明"; + } + } + + #endregion + + } } diff --git a/ElectronicObserver/Data/ShipData.cs b/ElectronicObserver/Data/ShipData.cs index eac6107f5..e46f1ee52 100644 --- a/ElectronicObserver/Data/ShipData.cs +++ b/ElectronicObserver/Data/ShipData.cs @@ -12,1539 +12,1539 @@ namespace ElectronicObserver.Data { - /// - /// 個別の艦娘データを保持します。 - /// - public class ShipData : APIWrapper, IIdentifiable - { + /// + /// 個別の艦娘データを保持します。 + /// + public class ShipData : APIWrapper, IIdentifiable + { - /// - /// 艦娘を一意に識別するID - /// - public int MasterID => (int)RawData.api_id; + /// + /// 艦娘を一意に識別するID + /// + public int MasterID => (int)RawData.api_id; - /// - /// 並べ替えの順番 - /// - public int SortID => (int)RawData.api_sortno; + /// + /// 並べ替えの順番 + /// + public int SortID => (int)RawData.api_sortno; - /// - /// 艦船ID - /// - public int ShipID => (int)RawData.api_ship_id; + /// + /// 艦船ID + /// + public int ShipID => (int)RawData.api_ship_id; - /// - /// レベル - /// - public int Level => (int)RawData.api_lv; + /// + /// レベル + /// + public int Level => (int)RawData.api_lv; - /// - /// 累積経験値 - /// - public int ExpTotal => (int)RawData.api_exp[0]; + /// + /// 累積経験値 + /// + public int ExpTotal => (int)RawData.api_exp[0]; - /// - /// 次のレベルに達するために必要な経験値 - /// - public int ExpNext => (int)RawData.api_exp[1]; + /// + /// 次のレベルに達するために必要な経験値 + /// + public int ExpNext => (int)RawData.api_exp[1]; - /// - /// 耐久現在値 - /// - public int HPCurrent { get; internal set; } + /// + /// 耐久現在値 + /// + public int HPCurrent { get; internal set; } - /// - /// 耐久最大値 - /// - public int HPMax => (int)RawData.api_maxhp; + /// + /// 耐久最大値 + /// + public int HPMax => (int)RawData.api_maxhp; - /// - /// 速力 - /// - public int Speed => RawData.api_soku() ? (int)RawData.api_soku : MasterShip.Speed; + /// + /// 速力 + /// + public int Speed => RawData.api_soku() ? (int)RawData.api_soku : MasterShip.Speed; - /// - /// 射程 - /// - public int Range => (int)RawData.api_leng; + /// + /// 射程 + /// + public int Range => (int)RawData.api_leng; - /// - /// 装備スロット(ID) - /// - public ReadOnlyCollection Slot { get; private set; } + /// + /// 装備スロット(ID) + /// + public ReadOnlyCollection Slot { get; private set; } - /// - /// 装備スロット(マスターID) - /// - public ReadOnlyCollection SlotMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); + /// + /// 装備スロット(マスターID) + /// + public ReadOnlyCollection SlotMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); - /// - /// 装備スロット(装備データ) - /// - public ReadOnlyCollection SlotInstance => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); + /// + /// 装備スロット(装備データ) + /// + public ReadOnlyCollection SlotInstance => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); - /// - /// 装備スロット(装備マスターデータ) - /// - public ReadOnlyCollection SlotInstanceMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); + /// + /// 装備スロット(装備マスターデータ) + /// + public ReadOnlyCollection SlotInstanceMaster => Array.AsReadOnly(Slot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); - /// - /// 補強装備スロット(ID) - /// 0=未開放, -1=装備なし - /// - public int ExpansionSlot { get; private set; } + /// + /// 補強装備スロット(ID) + /// 0=未開放, -1=装備なし + /// + public int ExpansionSlot { get; private set; } - /// - /// 補強装備スロット(マスターID) - /// - public int ExpansionSlotMaster => ExpansionSlot == 0 ? 0 : (KCDatabase.Instance.Equipments[ExpansionSlot]?.EquipmentID ?? -1); + /// + /// 補強装備スロット(マスターID) + /// + public int ExpansionSlotMaster => ExpansionSlot == 0 ? 0 : (KCDatabase.Instance.Equipments[ExpansionSlot]?.EquipmentID ?? -1); - /// - /// 補強装備スロット(装備データ) - /// - public EquipmentData ExpansionSlotInstance => KCDatabase.Instance.Equipments[ExpansionSlot]; + /// + /// 補強装備スロット(装備データ) + /// + public EquipmentData ExpansionSlotInstance => KCDatabase.Instance.Equipments[ExpansionSlot]; - /// - /// 補強装備スロット(装備マスターデータ) - /// - public EquipmentDataMaster ExpansionSlotInstanceMaster => KCDatabase.Instance.Equipments[ExpansionSlot]?.MasterEquipment; + /// + /// 補強装備スロット(装備マスターデータ) + /// + public EquipmentDataMaster ExpansionSlotInstanceMaster => KCDatabase.Instance.Equipments[ExpansionSlot]?.MasterEquipment; - /// - /// 全てのスロット(ID) - /// - public ReadOnlyCollection AllSlot => Array.AsReadOnly(Slot.Concat(new[] { ExpansionSlot }).ToArray()); + /// + /// 全てのスロット(ID) + /// + public ReadOnlyCollection AllSlot => Array.AsReadOnly(Slot.Concat(new[] { ExpansionSlot }).ToArray()); - /// - /// 全てのスロット(マスターID) - /// - public ReadOnlyCollection AllSlotMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); + /// + /// 全てのスロット(マスターID) + /// + public ReadOnlyCollection AllSlotMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.EquipmentID ?? -1).ToArray()); - /// - /// 全てのスロット(装備データ) - /// - public ReadOnlyCollection AllSlotInstance => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); + /// + /// 全てのスロット(装備データ) + /// + public ReadOnlyCollection AllSlotInstance => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]).ToArray()); - /// - /// 全てのスロット(装備マスターデータ) - /// - public ReadOnlyCollection AllSlotInstanceMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); + /// + /// 全てのスロット(装備マスターデータ) + /// + public ReadOnlyCollection AllSlotInstanceMaster => Array.AsReadOnly(AllSlot.Select(id => KCDatabase.Instance.Equipments[id]?.MasterEquipment).ToArray()); - private int[] _aircraft; - /// - /// 各スロットの航空機搭載量 - /// - public ReadOnlyCollection Aircraft => Array.AsReadOnly(_aircraft); + private int[] _aircraft; + /// + /// 各スロットの航空機搭載量 + /// + public ReadOnlyCollection Aircraft => Array.AsReadOnly(_aircraft); - /// - /// 現在の航空機搭載量 - /// - public int AircraftTotal => _aircraft.Sum(a => Math.Max(a, 0)); + /// + /// 現在の航空機搭載量 + /// + public int AircraftTotal => _aircraft.Sum(a => Math.Max(a, 0)); - /// - /// 搭載燃料 - /// - public int Fuel { get; internal set; } + /// + /// 搭載燃料 + /// + public int Fuel { get; internal set; } - /// - /// 搭載弾薬 - /// - public int Ammo { get; internal set; } + /// + /// 搭載弾薬 + /// + public int Ammo { get; internal set; } - /// - /// スロットのサイズ - /// - public int SlotSize => !RawData.api_slotnum() ? 0 : (int)RawData.api_slotnum; + /// + /// スロットのサイズ + /// + public int SlotSize => !RawData.api_slotnum() ? 0 : (int)RawData.api_slotnum; - /// - /// 入渠にかかる時間(ミリ秒) - /// - public int RepairTime => (int)RawData.api_ndock_time; + /// + /// 入渠にかかる時間(ミリ秒) + /// + public int RepairTime => (int)RawData.api_ndock_time; - /// - /// 入渠にかかる鋼材 - /// - public int RepairSteel => (int)RawData.api_ndock_item[1]; + /// + /// 入渠にかかる鋼材 + /// + public int RepairSteel => (int)RawData.api_ndock_item[1]; - /// - /// 入渠にかかる燃料 - /// - public int RepairFuel => (int)RawData.api_ndock_item[0]; + /// + /// 入渠にかかる燃料 + /// + public int RepairFuel => (int)RawData.api_ndock_item[0]; - /// - /// コンディション - /// - public int Condition { get; internal set; } + /// + /// コンディション + /// + public int Condition { get; internal set; } - #region Parameters + #region Parameters - /******************************************************** + /******************************************************** * 強化値:近代化改修・レベルアップによって上昇した数値 * 総合値:装備込みでのパラメータ * 基本値:装備なしでのパラメータ(初期値+強化値) ********************************************************/ - private int[] _modernized; - /// - /// 火力強化値 - /// - public int FirepowerModernized => _modernized.Length >= 5 ? _modernized[0] : 0; - - /// - /// 雷装強化値 - /// - public int TorpedoModernized => _modernized.Length >= 5 ? _modernized[1] : 0; - - /// - /// 対空強化値 - /// - public int AAModernized => _modernized.Length >= 5 ? _modernized[2] : 0; - - /// - /// 装甲強化値 - /// - public int ArmorModernized => _modernized.Length >= 5 ? _modernized[3] : 0; - - /// - /// 運強化値 - /// - public int LuckModernized => _modernized.Length >= 5 ? _modernized[4] : 0; - - /// - /// 耐久強化値 - /// - public int HPMaxModernized => _modernized.Length >= 7 ? _modernized[5] : 0; - - /// - /// 対潜強化値 - /// - public int ASWModernized => _modernized.Length >= 7 ? _modernized[6] : 0; - - - /// - /// 火力改修残り - /// - public int FirepowerRemain => (MasterShip.FirepowerMax - MasterShip.FirepowerMin) - FirepowerModernized; - - /// - /// 雷装改修残り - /// - public int TorpedoRemain => (MasterShip.TorpedoMax - MasterShip.TorpedoMin) - TorpedoModernized; - - /// - /// 対空改修残り - /// - public int AARemain => (MasterShip.AAMax - MasterShip.AAMin) - AAModernized; - - /// - /// 装甲改修残り - /// - public int ArmorRemain => (MasterShip.ArmorMax - MasterShip.ArmorMin) - ArmorModernized; - - /// - /// 運改修残り - /// - public int LuckRemain => (MasterShip.LuckMax - MasterShip.LuckMin) - LuckModernized; - - /// - /// 耐久改修残り - /// - public int HPMaxRemain => (IsMarried ? MasterShip.HPMaxMarriedModernizable : MasterShip.HPMaxModernizable) - HPMaxModernized; - - /// - /// 対潜改修残り - /// - public int ASWRemain => ASWMax <= 0 ? 0 : MasterShip.ASWModernizable - ASWModernized; - - - /// - /// 火力総合値 - /// - public int FirepowerTotal => (int)RawData.api_karyoku[0]; - - /// - /// 雷装総合値 - /// - public int TorpedoTotal => (int)RawData.api_raisou[0]; - - /// - /// 対空総合値 - /// - public int AATotal => (int)RawData.api_taiku[0]; - - /// - /// 装甲総合値 - /// - public int ArmorTotal => (int)RawData.api_soukou[0]; - - /// - /// 回避総合値 - /// - public int EvasionTotal => (int)RawData.api_kaihi[0]; - - /// - /// 対潜総合値 - /// - public int ASWTotal => (int)RawData.api_taisen[0]; - - /// - /// 索敵総合値 - /// - public int LOSTotal => (int)RawData.api_sakuteki[0]; - - /// - /// 運総合値 - /// - public int LuckTotal => (int)RawData.api_lucky[0]; - - /// - /// 爆装総合値 - /// - public int BomberTotal => AllSlotInstanceMaster.Sum(s => s == null ? 0 : Math.Max(s.Bomber, 0)); - - - /// - /// 火力基本値 - /// - public int FirepowerBase => MasterShip.FirepowerMin + FirepowerModernized; - - - /// - /// 雷装基本値 - /// - public int TorpedoBase => MasterShip.TorpedoMin + TorpedoModernized; - - - /// - /// 対空基本値 - /// - public int AABase => MasterShip.AAMin + AAModernized; - - - /// - /// 装甲基本値 - /// - public int ArmorBase => MasterShip.ArmorMin + ArmorModernized; - - - /// - /// 回避基本値 - /// - public int EvasionBase - { - get - { - int param = EvasionTotal; - bool hasNaganamiGun = false; - - var eqs = AllSlotInstance.Where(eq => eq != null); - foreach (var eq in eqs) - { - param -= eq.MasterEquipment.Evasion; - - if (eq.EquipmentID == 267) // 12.7cm連装砲D型改二 - { - hasNaganamiGun = true; - - if (ShipID == 543 || // 長波改二 - MasterShip.ShipClass == 22 || // 島風型 - MasterShip.ShipClass == 38 || // 夕雲型 - MasterShip.ShipClass == 30) // 陽炎型 - { - param -= 1; - } - } - } - - // 北方迷彩(+北方装備) による特殊補正(重複しない) - if (eqs.Any(eq => eq.EquipmentID == 268)) - { - switch (ShipID) - { - case 146: // 木曾改二 - case 216: // 多摩改 - case 217: // 木曾改 - case 547: // 多摩改二 - param -= 7; - break; - } - } - - // 12.7cm連装砲D型改二 + 水上電探 による特殊補正 - if (hasNaganamiGun && - (ShipID == 229 || ShipID == 543) && // 島風改, 長波改二 - eqs.Any(eq => eq.MasterEquipment.IsSurfaceRadar)) - { - param -= 2; - } - - return param; - } - } - - /// - /// 対潜基本値 - /// - public int ASWBase - { - get - { - int param = ASWTotal; - foreach (var eq in AllSlotInstance.Where(eq => eq != null)) - { - param -= eq.MasterEquipment.ASW; - } - return param; - } - } - - /// - /// 索敵基本値 - /// - public int LOSBase - { - get - { - int param = LOSTotal; - foreach (var eq in AllSlotInstance.Where(eq => eq != null)) - { - param -= eq.MasterEquipment.LOS; - } - return param; - } - } - - /// - /// 運基本値 - /// - public int LuckBase => MasterShip.LuckMin + LuckModernized; - - - - /// - /// 回避最大値 - /// - public int EvasionMax => (int)RawData.api_kaihi[1]; - - /// - /// 対潜最大値 - /// - public int ASWMax => (int)RawData.api_taisen[1]; - - /// - /// 索敵最大値 - /// - public int LOSMax => (int)RawData.api_sakuteki[1]; - - #endregion - - - /// - /// 保護ロックの有無 - /// - public bool IsLocked => (int)RawData.api_locked != 0; - - /// - /// 装備による保護ロックの有無 - /// - public bool IsLockedByEquipment => (int)RawData.api_locked_equip != 0; - - - /// - /// 出撃海域 - /// - public int SallyArea => RawData.api_sally_area() ? (int)RawData.api_sally_area : -1; - - - - /// - /// 艦船のマスターデータへの参照 - /// - public ShipDataMaster MasterShip => KCDatabase.Instance.MasterShips[ShipID]; - - - /// - /// 入渠中のドックID 非入渠時は-1 - /// - public int RepairingDockID => KCDatabase.Instance.Docks.Values.FirstOrDefault(dock => dock.ShipID == MasterID)?.DockID ?? -1; - - - /// - /// 所属艦隊 -1=なし - /// - public int Fleet => KCDatabase.Instance.Fleet.Fleets.Values.FirstOrDefault(f => f.Members.Contains(MasterID))?.FleetID ?? -1; - - - - /// - /// 所属艦隊及びその位置 - /// ex. 1-3 (位置も1から始まる) - /// 所属していなければ 空文字列 - /// - public string FleetWithIndex - { - get - { - FleetManager fm = KCDatabase.Instance.Fleet; - foreach (var f in fm.Fleets.Values) - { - int index = f.Members.IndexOf(MasterID); - if (index != -1) - { - return $"{f.FleetID}-{index + 1}"; - } - } - return ""; - } + private int[] _modernized; + /// + /// 火力強化値 + /// + public int FirepowerModernized => _modernized.Length >= 5 ? _modernized[0] : 0; + + /// + /// 雷装強化値 + /// + public int TorpedoModernized => _modernized.Length >= 5 ? _modernized[1] : 0; + + /// + /// 対空強化値 + /// + public int AAModernized => _modernized.Length >= 5 ? _modernized[2] : 0; + + /// + /// 装甲強化値 + /// + public int ArmorModernized => _modernized.Length >= 5 ? _modernized[3] : 0; + + /// + /// 運強化値 + /// + public int LuckModernized => _modernized.Length >= 5 ? _modernized[4] : 0; + + /// + /// 耐久強化値 + /// + public int HPMaxModernized => _modernized.Length >= 7 ? _modernized[5] : 0; + + /// + /// 対潜強化値 + /// + public int ASWModernized => _modernized.Length >= 7 ? _modernized[6] : 0; + + + /// + /// 火力改修残り + /// + public int FirepowerRemain => (MasterShip.FirepowerMax - MasterShip.FirepowerMin) - FirepowerModernized; + + /// + /// 雷装改修残り + /// + public int TorpedoRemain => (MasterShip.TorpedoMax - MasterShip.TorpedoMin) - TorpedoModernized; + + /// + /// 対空改修残り + /// + public int AARemain => (MasterShip.AAMax - MasterShip.AAMin) - AAModernized; + + /// + /// 装甲改修残り + /// + public int ArmorRemain => (MasterShip.ArmorMax - MasterShip.ArmorMin) - ArmorModernized; + + /// + /// 運改修残り + /// + public int LuckRemain => (MasterShip.LuckMax - MasterShip.LuckMin) - LuckModernized; + + /// + /// 耐久改修残り + /// + public int HPMaxRemain => (IsMarried ? MasterShip.HPMaxMarriedModernizable : MasterShip.HPMaxModernizable) - HPMaxModernized; + + /// + /// 対潜改修残り + /// + public int ASWRemain => ASWMax <= 0 ? 0 : MasterShip.ASWModernizable - ASWModernized; + + + /// + /// 火力総合値 + /// + public int FirepowerTotal => (int)RawData.api_karyoku[0]; + + /// + /// 雷装総合値 + /// + public int TorpedoTotal => (int)RawData.api_raisou[0]; + + /// + /// 対空総合値 + /// + public int AATotal => (int)RawData.api_taiku[0]; + + /// + /// 装甲総合値 + /// + public int ArmorTotal => (int)RawData.api_soukou[0]; + + /// + /// 回避総合値 + /// + public int EvasionTotal => (int)RawData.api_kaihi[0]; + + /// + /// 対潜総合値 + /// + public int ASWTotal => (int)RawData.api_taisen[0]; + + /// + /// 索敵総合値 + /// + public int LOSTotal => (int)RawData.api_sakuteki[0]; + + /// + /// 運総合値 + /// + public int LuckTotal => (int)RawData.api_lucky[0]; + + /// + /// 爆装総合値 + /// + public int BomberTotal => AllSlotInstanceMaster.Sum(s => s == null ? 0 : Math.Max(s.Bomber, 0)); + + + /// + /// 火力基本値 + /// + public int FirepowerBase => MasterShip.FirepowerMin + FirepowerModernized; + + + /// + /// 雷装基本値 + /// + public int TorpedoBase => MasterShip.TorpedoMin + TorpedoModernized; + + + /// + /// 対空基本値 + /// + public int AABase => MasterShip.AAMin + AAModernized; + + + /// + /// 装甲基本値 + /// + public int ArmorBase => MasterShip.ArmorMin + ArmorModernized; + + + /// + /// 回避基本値 + /// + public int EvasionBase + { + get + { + int param = EvasionTotal; + bool hasNaganamiGun = false; + + var eqs = AllSlotInstance.Where(eq => eq != null); + foreach (var eq in eqs) + { + param -= eq.MasterEquipment.Evasion; + + if (eq.EquipmentID == 267) // 12.7cm連装砲D型改二 + { + hasNaganamiGun = true; + + if (ShipID == 543 || // 長波改二 + MasterShip.ShipClass == 22 || // 島風型 + MasterShip.ShipClass == 38 || // 夕雲型 + MasterShip.ShipClass == 30) // 陽炎型 + { + param -= 1; + } + } + } + + // 北方迷彩(+北方装備) による特殊補正(重複しない) + if (eqs.Any(eq => eq.EquipmentID == 268)) + { + switch (ShipID) + { + case 146: // 木曾改二 + case 216: // 多摩改 + case 217: // 木曾改 + case 547: // 多摩改二 + param -= 7; + break; + } + } + + // 12.7cm連装砲D型改二 + 水上電探 による特殊補正 + if (hasNaganamiGun && + (ShipID == 229 || ShipID == 543) && // 島風改, 長波改二 + eqs.Any(eq => eq.MasterEquipment.IsSurfaceRadar)) + { + param -= 2; + } + + return param; + } + } + + /// + /// 対潜基本値 + /// + public int ASWBase + { + get + { + int param = ASWTotal; + foreach (var eq in AllSlotInstance.Where(eq => eq != null)) + { + param -= eq.MasterEquipment.ASW; + } + return param; + } + } + + /// + /// 索敵基本値 + /// + public int LOSBase + { + get + { + int param = LOSTotal; + foreach (var eq in AllSlotInstance.Where(eq => eq != null)) + { + param -= eq.MasterEquipment.LOS; + } + return param; + } + } + + /// + /// 運基本値 + /// + public int LuckBase => MasterShip.LuckMin + LuckModernized; + + + + /// + /// 回避最大値 + /// + public int EvasionMax => (int)RawData.api_kaihi[1]; + + /// + /// 対潜最大値 + /// + public int ASWMax => (int)RawData.api_taisen[1]; + + /// + /// 索敵最大値 + /// + public int LOSMax => (int)RawData.api_sakuteki[1]; + + #endregion + + + /// + /// 保護ロックの有無 + /// + public bool IsLocked => (int)RawData.api_locked != 0; + + /// + /// 装備による保護ロックの有無 + /// + public bool IsLockedByEquipment => (int)RawData.api_locked_equip != 0; + + + /// + /// 出撃海域 + /// + public int SallyArea => RawData.api_sally_area() ? (int)RawData.api_sally_area : -1; + + + + /// + /// 艦船のマスターデータへの参照 + /// + public ShipDataMaster MasterShip => KCDatabase.Instance.MasterShips[ShipID]; + + + /// + /// 入渠中のドックID 非入渠時は-1 + /// + public int RepairingDockID => KCDatabase.Instance.Docks.Values.FirstOrDefault(dock => dock.ShipID == MasterID)?.DockID ?? -1; + + + /// + /// 所属艦隊 -1=なし + /// + public int Fleet => KCDatabase.Instance.Fleet.Fleets.Values.FirstOrDefault(f => f.Members.Contains(MasterID))?.FleetID ?? -1; + + + + /// + /// 所属艦隊及びその位置 + /// ex. 1-3 (位置も1から始まる) + /// 所属していなければ 空文字列 + /// + public string FleetWithIndex + { + get + { + FleetManager fm = KCDatabase.Instance.Fleet; + foreach (var f in fm.Fleets.Values) + { + int index = f.Members.IndexOf(MasterID); + if (index != -1) + { + return $"{f.FleetID}-{index + 1}"; + } + } + return ""; + } - } + } - /// - /// ケッコン済みかどうか - /// - public bool IsMarried => Level > 99; + /// + /// ケッコン済みかどうか + /// + public bool IsMarried => Level > 99; - /// - /// 次の改装まで必要な経験値 - /// - public int ExpNextRemodel - { - get - { - ShipDataMaster master = MasterShip; - if (master.RemodelAfterShipID <= 0) - return 0; - return Math.Max(ExpTable.ShipExp[master.RemodelAfterLevel].Total - ExpTotal, 0); - } - } + /// + /// 次の改装まで必要な経験値 + /// + public int ExpNextRemodel + { + get + { + ShipDataMaster master = MasterShip; + if (master.RemodelAfterShipID <= 0) + return 0; + return Math.Max(ExpTable.ShipExp[master.RemodelAfterLevel].Total - ExpTotal, 0); + } + } - /// - /// 艦名 - /// - public string Name => MasterShip.Name; + /// + /// 艦名 + /// + public string Name => MasterShip.Name; - /// - /// 艦名(レベルを含む) - /// - public string NameWithLevel => $"{MasterShip.Name} Lv. {Level}"; + /// + /// 艦名(レベルを含む) + /// + public string NameWithLevel => $"{MasterShip.Name} Lv. {Level}"; - /// - /// HP/HPmax - /// - public double HPRate => HPMax > 0 ? (double)HPCurrent / HPMax : 0; + /// + /// HP/HPmax + /// + public double HPRate => HPMax > 0 ? (double)HPCurrent / HPMax : 0; - /// - /// 最大搭載燃料 - /// - public int FuelMax => MasterShip.Fuel; + /// + /// 最大搭載燃料 + /// + public int FuelMax => MasterShip.Fuel; - /// - /// 最大搭載弾薬 - /// - public int AmmoMax => MasterShip.Ammo; + /// + /// 最大搭載弾薬 + /// + public int AmmoMax => MasterShip.Ammo; - /// - /// 燃料残量割合 - /// - public double FuelRate => (double)Fuel / Math.Max(FuelMax, 1); + /// + /// 燃料残量割合 + /// + public double FuelRate => (double)Fuel / Math.Max(FuelMax, 1); - /// - /// 弾薬残量割合 - /// - public double AmmoRate => (double)Ammo / Math.Max(AmmoMax, 1); + /// + /// 弾薬残量割合 + /// + public double AmmoRate => (double)Ammo / Math.Max(AmmoMax, 1); - /// - /// 補給で消費する燃料 - /// - public int SupplyFuel => (FuelMax - Fuel) == 0 ? 0 : Math.Max((int)Math.Floor((FuelMax - Fuel) * (IsMarried ? 0.85 : 1)), 1); + /// + /// 補給で消費する燃料 + /// + public int SupplyFuel => (FuelMax - Fuel) == 0 ? 0 : Math.Max((int)Math.Floor((FuelMax - Fuel) * (IsMarried ? 0.85 : 1)), 1); - /// - /// 補給で消費する弾薬 - /// - public int SupplyAmmo => (AmmoMax - Ammo) == 0 ? 0 : Math.Max((int)Math.Floor((AmmoMax - Ammo) * (IsMarried ? 0.85 : 1)), 1); - - - /// - /// 搭載機残量割合 - /// - public ReadOnlyCollection AircraftRate - { - get - { - double[] airs = new double[_aircraft.Length]; - var airmax = MasterShip.Aircraft; - - for (int i = 0; i < airs.Length; i++) - { - airs[i] = (double)_aircraft[i] / Math.Max(airmax[i], 1); - } - - return Array.AsReadOnly(airs); - } - } - - /// - /// 搭載機残量割合 - /// - public double AircraftTotalRate => (double)AircraftTotal / Math.Max(MasterShip.AircraftTotal, 1); - - - - /// - /// 補強装備スロットが使用可能か - /// - public bool IsExpansionSlotAvailable => ExpansionSlot != 0; - - - - #region ダメージ威力計算 - - /// - /// 航空戦威力 - /// 本来スロットごとのものであるが、ここでは最大火力を採用する - /// - public int AirBattlePower => _airbattlePowers.Max(); - - private int[] _airbattlePowers; - /// - /// 各スロットの航空戦威力 - /// - public ReadOnlyCollection AirBattlePowers => Array.AsReadOnly(_airbattlePowers); - - /// - /// 砲撃威力 - /// - public int ShellingPower { get; private set; } - - //todo: ShellingPower に統合予定 - /// - /// 空撃威力 - /// - public int AircraftPower { get; private set; } - - /// - /// 対潜威力 - /// - public int AntiSubmarinePower { get; private set; } - - /// - /// 雷撃威力 - /// - public int TorpedoPower { get; private set; } - - /// - /// 夜戦威力 - /// - public int NightBattlePower { get; private set; } - - - - /// - /// 装備改修補正(砲撃戦) - /// - private double GetDayBattleEquipmentLevelBonus() - { - - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.MainGunLarge: - case EquipmentTypes.MainGunLarge2: - basepower += Math.Sqrt(slot.Level) * 1.5; - break; - - case EquipmentTypes.Sonar: - case EquipmentTypes.DepthCharge: - basepower += Math.Sqrt(slot.Level) * 0.75; - break; - - case EquipmentTypes.Torpedo: - case EquipmentTypes.SeaplaneRecon: - case EquipmentTypes.RadarSmall: - case EquipmentTypes.RadarLarge: - case EquipmentTypes.SubmarineTorpedo: - break; // → 無視 - - default: - basepower += Math.Sqrt(slot.Level); - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(空撃) - /// - /// - private double GetAircraftEquipmentLevelBonus() - { - - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.SecondaryGun: - basepower += Math.Sqrt(slot.Level); - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(雷撃戦) - /// - private double GetTorpedoEquipmentLevelBonus() - { - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.Torpedo: - case EquipmentTypes.AAGun: - case EquipmentTypes.SubmarineTorpedo: - basepower += Math.Sqrt(slot.Level) * 1.2; - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(対潜) - /// - private double GetAntiSubmarineEquipmentLevelBonus() - { - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.DepthCharge: - case EquipmentTypes.Sonar: - basepower += Math.Sqrt(slot.Level) * 1.2; - break; - } - } - return basepower; - } - - /// - /// 装備改修補正(夜戦) - /// - private double GetNightBattleEquipmentLevelBonus() - { - double basepower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.MainGunSmall: - case EquipmentTypes.MainGunMedium: - case EquipmentTypes.MainGunLarge: - case EquipmentTypes.SecondaryGun: - case EquipmentTypes.Torpedo: - case EquipmentTypes.APShell: - case EquipmentTypes.LandingCraft: - case EquipmentTypes.Searchlight: - case EquipmentTypes.SubmarineTorpedo: - case EquipmentTypes.AADirector: - case EquipmentTypes.MainGunLarge2: - case EquipmentTypes.SearchlightLarge: - case EquipmentTypes.SpecialAmphibiousTank: - basepower += Math.Sqrt(slot.Level); - break; - } - } - return basepower; - } - - /// - /// 耐久値による攻撃力補正 - /// - private double GetHPDamageBonus() - { - if (HPRate < 0.25) - return 0.4; - else if (HPRate < 0.5) - return 0.7; - else - return 1.0; - } - - /// - /// 耐久値による攻撃力補正(雷撃戦) - /// - /// - private double GetTorpedoHPDamageBonus() - { - if (HPRate < 0.25) - return 0.0; - else if (HPRate < 0.5) - return 0.8; - else - return 1.0; - } - - /// - /// 交戦形態による威力補正 - /// - private double GetEngagementFormDamageRate(int form) - { - switch (form) - { - case 1: // 同航戦 - default: - return 1.0; - case 2: // 反航戦 - return 0.8; - case 3: // T字有利 - return 1.2; - case 4: // T字不利 - return 0.6; - } - } - - /// - /// 残り弾薬量による威力補正 - /// - private double GetAmmoDamageRate() - { - return Math.Min(Math.Floor(AmmoRate * 100) / 50.0, 1.0); - } - - /// - /// 連合艦隊編成における砲撃戦火力補正 - /// - private double GetCombinedFleetShellingDamageBonus() - { - int fleet = Fleet; - if (fleet == -1 || fleet > 2) - return 0; - - switch (KCDatabase.Instance.Fleet.CombinedFlag) - { - case 1: //機動部隊 - if (fleet == 1) - return +2; - else - return +10; - - case 2: //水上部隊 - if (fleet == 1) - return +10; - else - return -5; - - case 3: //輸送部隊 - if (fleet == 1) - return -5; - else - return +10; - - default: - return 0; - } - } - - /// - /// 連合艦隊編成における雷撃戦火力補正 - /// - private double GetCombinedFleetTorpedoDamageBonus() - { - int fleet = Fleet; - if (fleet == -1 || fleet > 2) - return 0; - - if (KCDatabase.Instance.Fleet.CombinedFlag == 0) - return 0; - - return -5; - } - - /// - /// 軽巡軽量砲補正 - /// - private double GetLightCruiserDamageBonus() - { - if (MasterShip.ShipType == ShipTypes.LightCruiser || - MasterShip.ShipType == ShipTypes.TorpedoCruiser || - MasterShip.ShipType == ShipTypes.TrainingCruiser) - { - - int single = 0; - int twin = 0; - - foreach (var slot in AllSlotMaster) - { - if (slot == -1) continue; - - switch (slot) - { - case 4: // 14cm単装砲 - case 11: // 15.2cm単装砲 - single++; - break; - case 65: // 15.2cm連装砲 - case 119: // 14cm連装砲 - case 139: // 15.2cm連装砲改 - twin++; - break; - } - } - - return Math.Sqrt(twin) * 2.0 + Math.Sqrt(single); - } - - return 0; - } - - /// - /// イタリア重巡砲補正 - /// - /// - private double GetItalianDamageBonus() - { - switch (ShipID) - { - case 448: // Zara - case 358: // 改 - case 496: // due - case 449: // Pola - case 361: // 改 - return Math.Sqrt(AllSlotMaster.Count(id => id == 162)); // √( 203mm/53 連装砲 装備数 ) - - default: - return 0; - } - } - - private double CapDamage(double damage, int max) - { - if (damage < max) - return damage; - else - return max + Math.Sqrt(damage - max); - } - - - /// - /// 航空戦での威力を求めます。 - /// - /// スロットのインデックス。 0 起点です。 - private int CalculateAirBattlePower(int slotIndex) - { - double basepower = 0; - var slots = AllSlotInstance; - - var eq = SlotInstance[slotIndex]; - - if (eq == null || _aircraft[slotIndex] == 0) - return 0; - - switch (eq.MasterEquipment.CategoryType) - { - case EquipmentTypes.CarrierBasedBomber: - case EquipmentTypes.SeaplaneBomber: - case EquipmentTypes.JetBomber: // 通常航空戦においては /√2 されるが、とりあえず考えない - basepower = eq.MasterEquipment.Bomber * Math.Sqrt(_aircraft[slotIndex]) + 25; - break; - case EquipmentTypes.CarrierBasedTorpedo: - case EquipmentTypes.JetTorpedo: - // 150% 補正を引いたとする - basepower = (eq.MasterEquipment.Torpedo * Math.Sqrt(_aircraft[slotIndex]) + 25) * 1.5; - break; - default: - return 0; - } - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 150)); - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 砲撃戦での砲撃威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateShellingPower(int engagementForm = 1) - { - var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); - if (attackKind == DayAttackKind.AirAttack || attackKind == DayAttackKind.CutinAirAttack) - return 0; - - - double basepower = FirepowerTotal + GetDayBattleEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus() + 5; - - basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); - - // キャップ - basepower = Math.Floor(CapDamage(basepower, 180)); - - // 弾着観測射撃 - switch (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1)) - { - case DayAttackKind.DoubleShelling: - case DayAttackKind.CutinMainRadar: - basepower *= 1.2; - break; - case DayAttackKind.CutinMainSub: - basepower *= 1.1; - break; - case DayAttackKind.CutinMainAP: - basepower *= 1.3; - break; - case DayAttackKind.CutinMainMain: - basepower *= 1.5; - break; - } - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 砲撃戦での空撃威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateAircraftPower(int engagementForm = 1) - { - var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); - if (attackKind != DayAttackKind.AirAttack && attackKind != DayAttackKind.CutinAirAttack) - return 0; - - - double basepower = Math.Floor((FirepowerTotal + TorpedoTotal + Math.Floor(BomberTotal * 1.3) + GetAircraftEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus()) * 1.5) + 55; - - basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - // キャップ - basepower = Math.Floor(CapDamage(basepower, 180)); - - - // 空母カットイン - if (attackKind == DayAttackKind.CutinAirAttack) - { - var kind = Calculator.GetDayAirAttackCutinKind(SlotInstanceMaster); - switch (kind) - { - case DayAirAttackCutinKind.FighterBomberAttacker: - basepower *= 1.25; - break; - - case DayAirAttackCutinKind.BomberBomberAttacker: - basepower *= 1.20; - break; - - case DayAirAttackCutinKind.BomberAttacker: - basepower *= 1.15; - break; - } - } - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 砲撃戦での対潜威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateAntiSubmarinePower(int engagementForm = 1) - { - if (!CanAttackSubmarine) - return 0; - - double eqpower = 0; - foreach (var slot in AllSlotInstance) - { - if (slot == null) - continue; - - switch (slot.MasterEquipment.CategoryType) - { - case EquipmentTypes.CarrierBasedBomber: - case EquipmentTypes.CarrierBasedTorpedo: - case EquipmentTypes.SeaplaneBomber: - case EquipmentTypes.Sonar: - case EquipmentTypes.DepthCharge: - case EquipmentTypes.Autogyro: - case EquipmentTypes.ASPatrol: - case EquipmentTypes.SonarLarge: - eqpower += slot.MasterEquipment.ASW; - break; - } - } - - double basepower = Math.Sqrt(ASWBase) * 2 + eqpower * 1.5 + GetAntiSubmarineEquipmentLevelBonus(); - if (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, 126, false) == DayAttackKind.AirAttack) - { //126=伊168; 対潜攻撃が空撃なら - basepower += 8; - } - else - { //爆雷攻撃なら - basepower += 13; - } - - - basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - - //対潜シナジー - - int depthChargeCount = 0; - int depthChargeProjectorCount = 0; - int sonarCount = 0; // ソナーと大型ソナーの合算 - int largeSonarCount = 0; - - foreach (var slot in AllSlotInstanceMaster) - { - if (slot == null) - continue; - - switch (slot.CategoryType) - { - case EquipmentTypes.Sonar: - sonarCount++; - break; - case EquipmentTypes.DepthCharge: - if (slot.IsDepthCharge) - depthChargeCount++; - else - depthChargeProjectorCount++; - break; - case EquipmentTypes.SonarLarge: - largeSonarCount++; - sonarCount++; - break; - } - } - - double projector_sonar = depthChargeProjectorCount > 0 && sonarCount > 0 ? 1.15 : 1; - double charge_projector = depthChargeCount > 0 && depthChargeProjectorCount > 0 ? 1.1 : 1; - double charge_sonar = (!(projector_sonar > 1 && charge_projector > 1 && largeSonarCount > 0) && depthChargeCount > 0 && sonarCount > 0) ? 0.15 : 0; - - basepower *= projector_sonar * (charge_projector + charge_sonar); - - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 150)); - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 雷撃戦での威力を求めます。 - /// - /// 交戦形態。既定値は 1 (同航戦) です。 - private int CalculateTorpedoPower(int engagementForm = 1) - { - if (TorpedoBase == 0) - return 0; //雷撃不能艦は除外 - - double basepower = TorpedoTotal + GetTorpedoEquipmentLevelBonus() + GetCombinedFleetTorpedoDamageBonus() + 5; - - basepower *= GetTorpedoHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 150)); - - - return (int)(basepower * GetAmmoDamageRate()); - } - - /// - /// 夜戦での威力を求めます。 - /// - private int CalculateNightBattlePower() - { - var kind = Calculator.GetNightAttackKind(AllSlotMaster.ToArray(), ShipID, -1); - double basepower = 0; - - if (kind == NightAttackKind.CutinAirAttack) - { - var airs = SlotInstance.Zip(Aircraft, (eq, count) => new { eq, master = eq?.MasterEquipment, count }).Where(a => a.eq != null); - - basepower = FirepowerBase + - airs.Where(p => p.master.IsNightAircraft) - .Sum(p => p.master.Firepower + p.master.Torpedo + - 3 * p.count + - 0.45 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)) + - airs.Where(p => p.master.IsSwordfish || p.master.EquipmentID == 154) // 零戦62型(爆戦/岩井隊) - .Sum(p => p.master.Firepower + p.master.Torpedo + - 0.3 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)); - - } - else if (ShipID == 515 || ShipID == 393) - { // Ark Royal (改) - basepower = FirepowerBase + SlotInstanceMaster.Where(eq => eq?.IsSwordfish ?? false).Sum(eq => eq.Firepower + eq.Torpedo); - } - else - { - basepower = FirepowerTotal + TorpedoTotal + GetNightBattleEquipmentLevelBonus(); - } - - - basepower *= GetHPDamageBonus(); - - switch (kind) - { - case NightAttackKind.DoubleShelling: - basepower *= 1.2; - break; - - case NightAttackKind.CutinMainTorpedo: - basepower *= 1.3; - break; - - case NightAttackKind.CutinTorpedoTorpedo: - { - switch (Calculator.GetNightTorpedoCutinKind(AllSlotInstanceMaster, ShipID, -1)) - { - case NightTorpedoCutinKind.LateModelTorpedoSubmarineEquipment: - basepower *= 1.75; - break; - case NightTorpedoCutinKind.LateModelTorpedo2: - basepower *= 1.6; - break; - default: - basepower *= 1.5; - break; - } - } - break; - - case NightAttackKind.CutinMainSub: - basepower *= 1.75; - break; - - case NightAttackKind.CutinMainMain: - basepower *= 2.0; - break; - - case NightAttackKind.CutinAirAttack: - { - int nightFighter = SlotInstanceMaster.Count(eq => eq?.IsNightFighter ?? false); - int nightAttacker = SlotInstanceMaster.Count(eq => eq?.IsNightAttacker ?? false); - - if (nightFighter >= 2 && nightAttacker >= 1) - basepower *= 1.25; - else if (nightFighter >= 1 && nightAttacker >= 1) - basepower *= 1.2; - else - basepower *= 1.18; - } - break; - - case NightAttackKind.CutinTorpedoRadar: - if (ShipID == 543 && AllSlotInstanceMaster.Any(eq => eq?.EquipmentID == 267)) // 長波改二 + 12.7cm連装砲D型改二 - basepower *= 1.625; - else - basepower *= 1.3; - break; - - case NightAttackKind.CutinTorpedoPicket: - basepower *= 1.25; - break; - } - - basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); - - //キャップ - basepower = Math.Floor(CapDamage(basepower, 300)); - - - return (int)(basepower * GetAmmoDamageRate()); - } - - - /// - /// 威力系の計算をまとめて行い、プロパティを更新します。 - /// - private void CalculatePowers() - { - - int form = Utility.Configuration.Config.Control.PowerEngagementForm; - - _airbattlePowers = Slot.Select((_, i) => CalculateAirBattlePower(i)).ToArray(); - ShellingPower = CalculateShellingPower(form); - AircraftPower = CalculateAircraftPower(form); - AntiSubmarinePower = CalculateAntiSubmarinePower(form); - TorpedoPower = CalculateTorpedoPower(form); - NightBattlePower = CalculateNightBattlePower(); - - } - - - #endregion - - - - /// - /// 対潜攻撃可能か - /// - public bool CanAttackSubmarine - { - get - { - switch (MasterShip.ShipType) - { - case ShipTypes.Escort: - case ShipTypes.Destroyer: - case ShipTypes.LightCruiser: - case ShipTypes.TorpedoCruiser: - case ShipTypes.TrainingCruiser: - case ShipTypes.FleetOiler: - return ASWBase > 0; - - case ShipTypes.AviationCruiser: - case ShipTypes.LightAircraftCarrier: - case ShipTypes.AviationBattleship: - case ShipTypes.SeaplaneTender: - case ShipTypes.AmphibiousAssaultShip: - return AllSlotInstanceMaster.Any(eq => eq != null && eq.IsAntiSubmarineAircraft); - - default: - return false; - } - } - } - - /// - /// 開幕対潜攻撃可能か - /// - public bool CanOpeningASW - { - get - { - if (!CanAttackSubmarine) - return false; - - if (ShipID == 141) // 五十鈴改二 - return true; - - var eqs = AllSlotInstance.Where(eq => eq != null); - - if (ShipID == 380 || ShipID == 529) // 大鷹改(二) - { - if (ASWTotal >= 65) // 注: Lv. 1時点で対潜が 65 以上であるため、現時点では無条件に達成可能 - return true; - } - - if (ShipID == 526) // 大鷹 - { - // 対潜 7 以上の艦上攻撃機 - bool hasASWTorp = eqs.Any(eq => eq.MasterEquipment.CategoryType == EquipmentTypes.CarrierBasedTorpedo && eq.MasterEquipment.ASW >= 7); - if (hasASWTorp && ASWTotal >= 65) - return true; - } - - bool hasSonar = eqs.Any(eq => eq.MasterEquipment.IsSonar); - bool needSonar = !( - MasterShip.ShipType == ShipTypes.Escort && - ASWTotal >= 75 && - (ASWTotal - ASWBase) >= 4); - - if (needSonar && !hasSonar) - return false; - - if (MasterShip.ShipType == ShipTypes.Escort) - return ASWTotal >= 60; - else - return ASWTotal >= 100; - } - } - - - /// - /// 夜戦攻撃可能か - /// - public bool CanAttackAtNight - { - get - { - var master = MasterShip; - - if (HPRate <= 0.25) - return false; - - if (master.FirepowerMin + master.TorpedoMin > 0) - return true; - - // Ark Royal(改) - if (master.ShipID == 515 || master.ShipID == 393) - { - if (AllSlotInstanceMaster.Any(eq => eq != null && eq.IsSwordfish)) - return true; - } - - if (master.IsAircraftCarrier) - { - // 装甲空母ではなく、中破以上の被ダメージ - if (master.ShipType != ShipTypes.ArmoredAircraftCarrier && HPRate <= 0.5) - return false; - - // Saratoga Mk.II は不要 - bool hasNightPersonnel = master.ShipID == 545 || - AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAviationPersonnel); - - bool hasNightAircraft = AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAircraft); - - if (hasNightPersonnel && hasNightAircraft) - return true; - } - - return false; - } - } - - - /// - /// 発動可能なダメコンのID -1=なし, 42=要員, 43=女神 - /// - public int DamageControlID - { - get - { - if (ExpansionSlotMaster == 42 || ExpansionSlotMaster == 43) - return ExpansionSlotMaster; - - foreach (var eq in SlotMaster) - { - if (eq == 42 || eq == 43) - return eq; - } - - return -1; - } - } - - - - public int ID => MasterID; - public override string ToString() => $"[{MasterID}] {NameWithLevel}"; - - - public override void LoadFromResponse(string apiname, dynamic data) - { - - switch (apiname) - { - default: - base.LoadFromResponse(apiname, (object)data); - - HPCurrent = (int)RawData.api_nowhp; - Fuel = (int)RawData.api_fuel; - Ammo = (int)RawData.api_bull; - Condition = (int)RawData.api_cond; - Slot = Array.AsReadOnly((int[])RawData.api_slot); - ExpansionSlot = (int)RawData.api_slot_ex; - _aircraft = (int[])RawData.api_onslot; - _modernized = (int[])RawData.api_kyouka; - break; - - case "api_req_hokyu/charge": - Fuel = (int)data.api_fuel; - Ammo = (int)data.api_bull; - _aircraft = (int[])data.api_onslot; - break; - - case "api_req_kaisou/slot_exchange_index": - Slot = Array.AsReadOnly((int[])data.api_slot); - break; - } + /// + /// 補給で消費する弾薬 + /// + public int SupplyAmmo => (AmmoMax - Ammo) == 0 ? 0 : Math.Max((int)Math.Floor((AmmoMax - Ammo) * (IsMarried ? 0.85 : 1)), 1); + + + /// + /// 搭載機残量割合 + /// + public ReadOnlyCollection AircraftRate + { + get + { + double[] airs = new double[_aircraft.Length]; + var airmax = MasterShip.Aircraft; + + for (int i = 0; i < airs.Length; i++) + { + airs[i] = (double)_aircraft[i] / Math.Max(airmax[i], 1); + } + + return Array.AsReadOnly(airs); + } + } + + /// + /// 搭載機残量割合 + /// + public double AircraftTotalRate => (double)AircraftTotal / Math.Max(MasterShip.AircraftTotal, 1); + + + + /// + /// 補強装備スロットが使用可能か + /// + public bool IsExpansionSlotAvailable => ExpansionSlot != 0; + + + + #region ダメージ威力計算 + + /// + /// 航空戦威力 + /// 本来スロットごとのものであるが、ここでは最大火力を採用する + /// + public int AirBattlePower => _airbattlePowers.Max(); + + private int[] _airbattlePowers; + /// + /// 各スロットの航空戦威力 + /// + public ReadOnlyCollection AirBattlePowers => Array.AsReadOnly(_airbattlePowers); + + /// + /// 砲撃威力 + /// + public int ShellingPower { get; private set; } + + //todo: ShellingPower に統合予定 + /// + /// 空撃威力 + /// + public int AircraftPower { get; private set; } + + /// + /// 対潜威力 + /// + public int AntiSubmarinePower { get; private set; } + + /// + /// 雷撃威力 + /// + public int TorpedoPower { get; private set; } + + /// + /// 夜戦威力 + /// + public int NightBattlePower { get; private set; } + + + + /// + /// 装備改修補正(砲撃戦) + /// + private double GetDayBattleEquipmentLevelBonus() + { + + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.MainGunLarge: + case EquipmentTypes.MainGunLarge2: + basepower += Math.Sqrt(slot.Level) * 1.5; + break; + + case EquipmentTypes.Sonar: + case EquipmentTypes.DepthCharge: + basepower += Math.Sqrt(slot.Level) * 0.75; + break; + + case EquipmentTypes.Torpedo: + case EquipmentTypes.SeaplaneRecon: + case EquipmentTypes.RadarSmall: + case EquipmentTypes.RadarLarge: + case EquipmentTypes.SubmarineTorpedo: + break; // → 無視 + + default: + basepower += Math.Sqrt(slot.Level); + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(空撃) + /// + /// + private double GetAircraftEquipmentLevelBonus() + { + + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.SecondaryGun: + basepower += Math.Sqrt(slot.Level); + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(雷撃戦) + /// + private double GetTorpedoEquipmentLevelBonus() + { + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.Torpedo: + case EquipmentTypes.AAGun: + case EquipmentTypes.SubmarineTorpedo: + basepower += Math.Sqrt(slot.Level) * 1.2; + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(対潜) + /// + private double GetAntiSubmarineEquipmentLevelBonus() + { + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.DepthCharge: + case EquipmentTypes.Sonar: + basepower += Math.Sqrt(slot.Level) * 1.2; + break; + } + } + return basepower; + } + + /// + /// 装備改修補正(夜戦) + /// + private double GetNightBattleEquipmentLevelBonus() + { + double basepower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.MainGunSmall: + case EquipmentTypes.MainGunMedium: + case EquipmentTypes.MainGunLarge: + case EquipmentTypes.SecondaryGun: + case EquipmentTypes.Torpedo: + case EquipmentTypes.APShell: + case EquipmentTypes.LandingCraft: + case EquipmentTypes.Searchlight: + case EquipmentTypes.SubmarineTorpedo: + case EquipmentTypes.AADirector: + case EquipmentTypes.MainGunLarge2: + case EquipmentTypes.SearchlightLarge: + case EquipmentTypes.SpecialAmphibiousTank: + basepower += Math.Sqrt(slot.Level); + break; + } + } + return basepower; + } + + /// + /// 耐久値による攻撃力補正 + /// + private double GetHPDamageBonus() + { + if (HPRate < 0.25) + return 0.4; + else if (HPRate < 0.5) + return 0.7; + else + return 1.0; + } + + /// + /// 耐久値による攻撃力補正(雷撃戦) + /// + /// + private double GetTorpedoHPDamageBonus() + { + if (HPRate < 0.25) + return 0.0; + else if (HPRate < 0.5) + return 0.8; + else + return 1.0; + } + + /// + /// 交戦形態による威力補正 + /// + private double GetEngagementFormDamageRate(int form) + { + switch (form) + { + case 1: // 同航戦 + default: + return 1.0; + case 2: // 反航戦 + return 0.8; + case 3: // T字有利 + return 1.2; + case 4: // T字不利 + return 0.6; + } + } + + /// + /// 残り弾薬量による威力補正 + /// + private double GetAmmoDamageRate() + { + return Math.Min(Math.Floor(AmmoRate * 100) / 50.0, 1.0); + } + + /// + /// 連合艦隊編成における砲撃戦火力補正 + /// + private double GetCombinedFleetShellingDamageBonus() + { + int fleet = Fleet; + if (fleet == -1 || fleet > 2) + return 0; + + switch (KCDatabase.Instance.Fleet.CombinedFlag) + { + case 1: //機動部隊 + if (fleet == 1) + return +2; + else + return +10; + + case 2: //水上部隊 + if (fleet == 1) + return +10; + else + return -5; + + case 3: //輸送部隊 + if (fleet == 1) + return -5; + else + return +10; + + default: + return 0; + } + } + + /// + /// 連合艦隊編成における雷撃戦火力補正 + /// + private double GetCombinedFleetTorpedoDamageBonus() + { + int fleet = Fleet; + if (fleet == -1 || fleet > 2) + return 0; + + if (KCDatabase.Instance.Fleet.CombinedFlag == 0) + return 0; + + return -5; + } + + /// + /// 軽巡軽量砲補正 + /// + private double GetLightCruiserDamageBonus() + { + if (MasterShip.ShipType == ShipTypes.LightCruiser || + MasterShip.ShipType == ShipTypes.TorpedoCruiser || + MasterShip.ShipType == ShipTypes.TrainingCruiser) + { + + int single = 0; + int twin = 0; + + foreach (var slot in AllSlotMaster) + { + if (slot == -1) continue; + + switch (slot) + { + case 4: // 14cm単装砲 + case 11: // 15.2cm単装砲 + single++; + break; + case 65: // 15.2cm連装砲 + case 119: // 14cm連装砲 + case 139: // 15.2cm連装砲改 + twin++; + break; + } + } + + return Math.Sqrt(twin) * 2.0 + Math.Sqrt(single); + } + + return 0; + } + + /// + /// イタリア重巡砲補正 + /// + /// + private double GetItalianDamageBonus() + { + switch (ShipID) + { + case 448: // Zara + case 358: // 改 + case 496: // due + case 449: // Pola + case 361: // 改 + return Math.Sqrt(AllSlotMaster.Count(id => id == 162)); // √( 203mm/53 連装砲 装備数 ) + + default: + return 0; + } + } + + private double CapDamage(double damage, int max) + { + if (damage < max) + return damage; + else + return max + Math.Sqrt(damage - max); + } + + + /// + /// 航空戦での威力を求めます。 + /// + /// スロットのインデックス。 0 起点です。 + private int CalculateAirBattlePower(int slotIndex) + { + double basepower = 0; + var slots = AllSlotInstance; + + var eq = SlotInstance[slotIndex]; + + if (eq == null || _aircraft[slotIndex] == 0) + return 0; + + switch (eq.MasterEquipment.CategoryType) + { + case EquipmentTypes.CarrierBasedBomber: + case EquipmentTypes.SeaplaneBomber: + case EquipmentTypes.JetBomber: // 通常航空戦においては /√2 されるが、とりあえず考えない + basepower = eq.MasterEquipment.Bomber * Math.Sqrt(_aircraft[slotIndex]) + 25; + break; + case EquipmentTypes.CarrierBasedTorpedo: + case EquipmentTypes.JetTorpedo: + // 150% 補正を引いたとする + basepower = (eq.MasterEquipment.Torpedo * Math.Sqrt(_aircraft[slotIndex]) + 25) * 1.5; + break; + default: + return 0; + } + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 150)); + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 砲撃戦での砲撃威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateShellingPower(int engagementForm = 1) + { + var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); + if (attackKind == DayAttackKind.AirAttack || attackKind == DayAttackKind.CutinAirAttack) + return 0; + + + double basepower = FirepowerTotal + GetDayBattleEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus() + 5; + + basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); + + // キャップ + basepower = Math.Floor(CapDamage(basepower, 180)); + + // 弾着観測射撃 + switch (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1)) + { + case DayAttackKind.DoubleShelling: + case DayAttackKind.CutinMainRadar: + basepower *= 1.2; + break; + case DayAttackKind.CutinMainSub: + basepower *= 1.1; + break; + case DayAttackKind.CutinMainAP: + basepower *= 1.3; + break; + case DayAttackKind.CutinMainMain: + basepower *= 1.5; + break; + } + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 砲撃戦での空撃威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateAircraftPower(int engagementForm = 1) + { + var attackKind = Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, -1, false); + if (attackKind != DayAttackKind.AirAttack && attackKind != DayAttackKind.CutinAirAttack) + return 0; + + + double basepower = Math.Floor((FirepowerTotal + TorpedoTotal + Math.Floor(BomberTotal * 1.3) + GetAircraftEquipmentLevelBonus() + GetCombinedFleetShellingDamageBonus()) * 1.5) + 55; + + basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + // キャップ + basepower = Math.Floor(CapDamage(basepower, 180)); + + + // 空母カットイン + if (attackKind == DayAttackKind.CutinAirAttack) + { + var kind = Calculator.GetDayAirAttackCutinKind(SlotInstanceMaster); + switch (kind) + { + case DayAirAttackCutinKind.FighterBomberAttacker: + basepower *= 1.25; + break; + + case DayAirAttackCutinKind.BomberBomberAttacker: + basepower *= 1.20; + break; + + case DayAirAttackCutinKind.BomberAttacker: + basepower *= 1.15; + break; + } + } + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 砲撃戦での対潜威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateAntiSubmarinePower(int engagementForm = 1) + { + if (!CanAttackSubmarine) + return 0; + + double eqpower = 0; + foreach (var slot in AllSlotInstance) + { + if (slot == null) + continue; + + switch (slot.MasterEquipment.CategoryType) + { + case EquipmentTypes.CarrierBasedBomber: + case EquipmentTypes.CarrierBasedTorpedo: + case EquipmentTypes.SeaplaneBomber: + case EquipmentTypes.Sonar: + case EquipmentTypes.DepthCharge: + case EquipmentTypes.Autogyro: + case EquipmentTypes.ASPatrol: + case EquipmentTypes.SonarLarge: + eqpower += slot.MasterEquipment.ASW; + break; + } + } + + double basepower = Math.Sqrt(ASWBase) * 2 + eqpower * 1.5 + GetAntiSubmarineEquipmentLevelBonus(); + if (Calculator.GetDayAttackKind(AllSlotMaster.ToArray(), ShipID, 126, false) == DayAttackKind.AirAttack) + { //126=伊168; 対潜攻撃が空撃なら + basepower += 8; + } + else + { //爆雷攻撃なら + basepower += 13; + } + + + basepower *= GetHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + + //対潜シナジー + + int depthChargeCount = 0; + int depthChargeProjectorCount = 0; + int sonarCount = 0; // ソナーと大型ソナーの合算 + int largeSonarCount = 0; + + foreach (var slot in AllSlotInstanceMaster) + { + if (slot == null) + continue; + + switch (slot.CategoryType) + { + case EquipmentTypes.Sonar: + sonarCount++; + break; + case EquipmentTypes.DepthCharge: + if (slot.IsDepthCharge) + depthChargeCount++; + else + depthChargeProjectorCount++; + break; + case EquipmentTypes.SonarLarge: + largeSonarCount++; + sonarCount++; + break; + } + } + + double projector_sonar = depthChargeProjectorCount > 0 && sonarCount > 0 ? 1.15 : 1; + double charge_projector = depthChargeCount > 0 && depthChargeProjectorCount > 0 ? 1.1 : 1; + double charge_sonar = (!(projector_sonar > 1 && charge_projector > 1 && largeSonarCount > 0) && depthChargeCount > 0 && sonarCount > 0) ? 0.15 : 0; + + basepower *= projector_sonar * (charge_projector + charge_sonar); + + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 150)); + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 雷撃戦での威力を求めます。 + /// + /// 交戦形態。既定値は 1 (同航戦) です。 + private int CalculateTorpedoPower(int engagementForm = 1) + { + if (TorpedoBase == 0) + return 0; //雷撃不能艦は除外 + + double basepower = TorpedoTotal + GetTorpedoEquipmentLevelBonus() + GetCombinedFleetTorpedoDamageBonus() + 5; + + basepower *= GetTorpedoHPDamageBonus() * GetEngagementFormDamageRate(engagementForm); + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 150)); + + + return (int)(basepower * GetAmmoDamageRate()); + } + + /// + /// 夜戦での威力を求めます。 + /// + private int CalculateNightBattlePower() + { + var kind = Calculator.GetNightAttackKind(AllSlotMaster.ToArray(), ShipID, -1); + double basepower = 0; + + if (kind == NightAttackKind.CutinAirAttack) + { + var airs = SlotInstance.Zip(Aircraft, (eq, count) => new { eq, master = eq?.MasterEquipment, count }).Where(a => a.eq != null); + + basepower = FirepowerBase + + airs.Where(p => p.master.IsNightAircraft) + .Sum(p => p.master.Firepower + p.master.Torpedo + + 3 * p.count + + 0.45 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)) + + airs.Where(p => p.master.IsSwordfish || p.master.EquipmentID == 154) // 零戦62型(爆戦/岩井隊) + .Sum(p => p.master.Firepower + p.master.Torpedo + + 0.3 * (p.master.Firepower + p.master.Torpedo + p.master.Bomber + p.master.ASW) * Math.Sqrt(p.count) + Math.Sqrt(p.eq.Level)); + + } + else if (ShipID == 515 || ShipID == 393) + { // Ark Royal (改) + basepower = FirepowerBase + SlotInstanceMaster.Where(eq => eq?.IsSwordfish ?? false).Sum(eq => eq.Firepower + eq.Torpedo); + } + else + { + basepower = FirepowerTotal + TorpedoTotal + GetNightBattleEquipmentLevelBonus(); + } + + + basepower *= GetHPDamageBonus(); + + switch (kind) + { + case NightAttackKind.DoubleShelling: + basepower *= 1.2; + break; + + case NightAttackKind.CutinMainTorpedo: + basepower *= 1.3; + break; + + case NightAttackKind.CutinTorpedoTorpedo: + { + switch (Calculator.GetNightTorpedoCutinKind(AllSlotInstanceMaster, ShipID, -1)) + { + case NightTorpedoCutinKind.LateModelTorpedoSubmarineEquipment: + basepower *= 1.75; + break; + case NightTorpedoCutinKind.LateModelTorpedo2: + basepower *= 1.6; + break; + default: + basepower *= 1.5; + break; + } + } + break; + + case NightAttackKind.CutinMainSub: + basepower *= 1.75; + break; + + case NightAttackKind.CutinMainMain: + basepower *= 2.0; + break; + + case NightAttackKind.CutinAirAttack: + { + int nightFighter = SlotInstanceMaster.Count(eq => eq?.IsNightFighter ?? false); + int nightAttacker = SlotInstanceMaster.Count(eq => eq?.IsNightAttacker ?? false); + + if (nightFighter >= 2 && nightAttacker >= 1) + basepower *= 1.25; + else if (nightFighter >= 1 && nightAttacker >= 1) + basepower *= 1.2; + else + basepower *= 1.18; + } + break; + + case NightAttackKind.CutinTorpedoRadar: + if (ShipID == 543 && AllSlotInstanceMaster.Any(eq => eq?.EquipmentID == 267)) // 長波改二 + 12.7cm連装砲D型改二 + basepower *= 1.625; + else + basepower *= 1.3; + break; + + case NightAttackKind.CutinTorpedoPicket: + basepower *= 1.25; + break; + } + + basepower += GetLightCruiserDamageBonus() + GetItalianDamageBonus(); + + //キャップ + basepower = Math.Floor(CapDamage(basepower, 300)); + + + return (int)(basepower * GetAmmoDamageRate()); + } + + + /// + /// 威力系の計算をまとめて行い、プロパティを更新します。 + /// + private void CalculatePowers() + { + + int form = Utility.Configuration.Config.Control.PowerEngagementForm; + + _airbattlePowers = Slot.Select((_, i) => CalculateAirBattlePower(i)).ToArray(); + ShellingPower = CalculateShellingPower(form); + AircraftPower = CalculateAircraftPower(form); + AntiSubmarinePower = CalculateAntiSubmarinePower(form); + TorpedoPower = CalculateTorpedoPower(form); + NightBattlePower = CalculateNightBattlePower(); + + } + + + #endregion + + + + /// + /// 対潜攻撃可能か + /// + public bool CanAttackSubmarine + { + get + { + switch (MasterShip.ShipType) + { + case ShipTypes.Escort: + case ShipTypes.Destroyer: + case ShipTypes.LightCruiser: + case ShipTypes.TorpedoCruiser: + case ShipTypes.TrainingCruiser: + case ShipTypes.FleetOiler: + return ASWBase > 0; + + case ShipTypes.AviationCruiser: + case ShipTypes.LightAircraftCarrier: + case ShipTypes.AviationBattleship: + case ShipTypes.SeaplaneTender: + case ShipTypes.AmphibiousAssaultShip: + return AllSlotInstanceMaster.Any(eq => eq != null && eq.IsAntiSubmarineAircraft); + + default: + return false; + } + } + } + + /// + /// 開幕対潜攻撃可能か + /// + public bool CanOpeningASW + { + get + { + if (!CanAttackSubmarine) + return false; + + if (ShipID == 141) // 五十鈴改二 + return true; + + var eqs = AllSlotInstance.Where(eq => eq != null); + + if (ShipID == 380 || ShipID == 529) // 大鷹改(二) + { + if (ASWTotal >= 65) // 注: Lv. 1時点で対潜が 65 以上であるため、現時点では無条件に達成可能 + return true; + } + + if (ShipID == 526) // 大鷹 + { + // 対潜 7 以上の艦上攻撃機 + bool hasASWTorp = eqs.Any(eq => eq.MasterEquipment.CategoryType == EquipmentTypes.CarrierBasedTorpedo && eq.MasterEquipment.ASW >= 7); + if (hasASWTorp && ASWTotal >= 65) + return true; + } + + bool hasSonar = eqs.Any(eq => eq.MasterEquipment.IsSonar); + bool needSonar = !( + MasterShip.ShipType == ShipTypes.Escort && + ASWTotal >= 75 && + (ASWTotal - ASWBase) >= 4); + + if (needSonar && !hasSonar) + return false; + + if (MasterShip.ShipType == ShipTypes.Escort) + return ASWTotal >= 60; + else + return ASWTotal >= 100; + } + } + + + /// + /// 夜戦攻撃可能か + /// + public bool CanAttackAtNight + { + get + { + var master = MasterShip; + + if (HPRate <= 0.25) + return false; + + if (master.FirepowerMin + master.TorpedoMin > 0) + return true; + + // Ark Royal(改) + if (master.ShipID == 515 || master.ShipID == 393) + { + if (AllSlotInstanceMaster.Any(eq => eq != null && eq.IsSwordfish)) + return true; + } + + if (master.IsAircraftCarrier) + { + // 装甲空母ではなく、中破以上の被ダメージ + if (master.ShipType != ShipTypes.ArmoredAircraftCarrier && HPRate <= 0.5) + return false; + + // Saratoga Mk.II は不要 + bool hasNightPersonnel = master.ShipID == 545 || + AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAviationPersonnel); + + bool hasNightAircraft = AllSlotInstanceMaster.Any(eq => eq != null && eq.IsNightAircraft); + + if (hasNightPersonnel && hasNightAircraft) + return true; + } + + return false; + } + } + + + /// + /// 発動可能なダメコンのID -1=なし, 42=要員, 43=女神 + /// + public int DamageControlID + { + get + { + if (ExpansionSlotMaster == 42 || ExpansionSlotMaster == 43) + return ExpansionSlotMaster; + + foreach (var eq in SlotMaster) + { + if (eq == 42 || eq == 43) + return eq; + } + + return -1; + } + } + + + + public int ID => MasterID; + public override string ToString() => $"[{MasterID}] {NameWithLevel}"; + + + public override void LoadFromResponse(string apiname, dynamic data) + { + + switch (apiname) + { + default: + base.LoadFromResponse(apiname, (object)data); + + HPCurrent = (int)RawData.api_nowhp; + Fuel = (int)RawData.api_fuel; + Ammo = (int)RawData.api_bull; + Condition = (int)RawData.api_cond; + Slot = Array.AsReadOnly((int[])RawData.api_slot); + ExpansionSlot = (int)RawData.api_slot_ex; + _aircraft = (int[])RawData.api_onslot; + _modernized = (int[])RawData.api_kyouka; + break; + + case "api_req_hokyu/charge": + Fuel = (int)data.api_fuel; + Ammo = (int)data.api_bull; + _aircraft = (int[])data.api_onslot; + break; + + case "api_req_kaisou/slot_exchange_index": + Slot = Array.AsReadOnly((int[])data.api_slot); + break; + } - CalculatePowers(); - } - - - public override void LoadFromRequest(string apiname, Dictionary data) - { - base.LoadFromRequest(apiname, data); + CalculatePowers(); + } + + + public override void LoadFromRequest(string apiname, Dictionary data) + { + base.LoadFromRequest(apiname, data); - KCDatabase db = KCDatabase.Instance; + KCDatabase db = KCDatabase.Instance; - switch (apiname) - { - case "api_req_kousyou/destroyship": - { - for (int i = 0; i < Slot.Count; i++) - { - if (Slot[i] == -1) - continue; + switch (apiname) + { + case "api_req_kousyou/destroyship": + { + for (int i = 0; i < Slot.Count; i++) + { + if (Slot[i] == -1) + continue; - db.Equipments.Remove(Slot[i]); - } - } - break; + db.Equipments.Remove(Slot[i]); + } + } + break; - case "api_req_kaisou/open_exslot": - ExpansionSlot = -1; - break; - } - } + case "api_req_kaisou/open_exslot": + ExpansionSlot = -1; + break; + } + } - /// - /// 入渠完了時の処理を行います。 - /// - internal void Repair() - { + /// + /// 入渠完了時の処理を行います。 + /// + internal void Repair() + { - HPCurrent = HPMax; - Condition = Math.Max(Condition, 40); + HPCurrent = HPMax; + Condition = Math.Max(Condition, 40); - RawData.api_ndock_time = 0; - RawData.api_ndock_item[0] = 0; - RawData.api_ndock_item[1] = 0; + RawData.api_ndock_time = 0; + RawData.api_ndock_item[0] = 0; + RawData.api_ndock_item[1] = 0; - } + } - } + } } diff --git a/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs b/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs index 5cc2fc902..a5a5e17c6 100644 --- a/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs +++ b/ElectronicObserver/Window/Dialog/DialogAlbumMasterShip.cs @@ -18,1588 +18,1588 @@ namespace ElectronicObserver.Window.Dialog { - public partial class DialogAlbumMasterShip : Form - { - - private int _shipID; - - private ImageLabel[] Aircrafts; - private ImageLabel[] Equipments; - - private int loadingResourceShipID; - - - public DialogAlbumMasterShip() - { - InitializeComponent(); - - Aircrafts = new ImageLabel[] { Aircraft1, Aircraft2, Aircraft3, Aircraft4, Aircraft5 }; - Equipments = new ImageLabel[] { Equipment1, Equipment2, Equipment3, Equipment4, Equipment5 }; - - loadingResourceShipID = -1; - - TitleHP.ImageList = - TitleFirepower.ImageList = - TitleTorpedo.ImageList = - TitleAA.ImageList = - TitleArmor.ImageList = - TitleASW.ImageList = - TitleEvasion.ImageList = - TitleLOS.ImageList = - TitleLuck.ImageList = - TitleSpeed.ImageList = - TitleRange.ImageList = - Rarity.ImageList = - Fuel.ImageList = - Ammo.ImageList = - TitleBuildingTime.ImageList = - MaterialFuel.ImageList = - MaterialAmmo.ImageList = - MaterialSteel.ImageList = - MaterialBauxite.ImageList = - PowerUpFirepower.ImageList = - PowerUpTorpedo.ImageList = - PowerUpAA.ImageList = - PowerUpArmor.ImageList = - RemodelBeforeLevel.ImageList = - RemodelBeforeAmmo.ImageList = - RemodelBeforeSteel.ImageList = - RemodelAfterLevel.ImageList = - RemodelAfterAmmo.ImageList = - RemodelAfterSteel.ImageList = - ResourceManager.Instance.Icons; - - TitleAirSuperiority.ImageList = - TitleDayAttack.ImageList = - TitleNightAttack.ImageList = - Equipment1.ImageList = - Equipment2.ImageList = - Equipment3.ImageList = - Equipment4.ImageList = - Equipment5.ImageList = - ResourceManager.Instance.Equipments; - - TitleHP.ImageIndex = (int)ResourceManager.IconContent.ParameterHP; - TitleFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; - TitleTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; - TitleAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; - TitleArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; - TitleASW.ImageIndex = (int)ResourceManager.IconContent.ParameterASW; - TitleEvasion.ImageIndex = (int)ResourceManager.IconContent.ParameterEvasion; - TitleLOS.ImageIndex = (int)ResourceManager.IconContent.ParameterLOS; - TitleLuck.ImageIndex = (int)ResourceManager.IconContent.ParameterLuck; - TitleSpeed.ImageIndex = (int)ResourceManager.IconContent.ParameterSpeed; - TitleRange.ImageIndex = (int)ResourceManager.IconContent.ParameterRange; - Fuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; - Ammo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - TitleBuildingTime.ImageIndex = (int)ResourceManager.IconContent.FormArsenal; - MaterialFuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; - MaterialAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - MaterialSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; - MaterialBauxite.ImageIndex = (int)ResourceManager.IconContent.ResourceBauxite; - PowerUpFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; - PowerUpTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; - PowerUpAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; - PowerUpArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; - RemodelBeforeAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - RemodelBeforeSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; - RemodelAfterAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; - RemodelAfterSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; - TitleAirSuperiority.ImageIndex = (int)ResourceManager.EquipmentContent.CarrierBasedFighter; - TitleDayAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Seaplane; - TitleNightAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Torpedo; + public partial class DialogAlbumMasterShip : Form + { + + private int _shipID; + + private ImageLabel[] Aircrafts; + private ImageLabel[] Equipments; + + private int loadingResourceShipID; + + + public DialogAlbumMasterShip() + { + InitializeComponent(); + + Aircrafts = new ImageLabel[] { Aircraft1, Aircraft2, Aircraft3, Aircraft4, Aircraft5 }; + Equipments = new ImageLabel[] { Equipment1, Equipment2, Equipment3, Equipment4, Equipment5 }; + + loadingResourceShipID = -1; + + TitleHP.ImageList = + TitleFirepower.ImageList = + TitleTorpedo.ImageList = + TitleAA.ImageList = + TitleArmor.ImageList = + TitleASW.ImageList = + TitleEvasion.ImageList = + TitleLOS.ImageList = + TitleLuck.ImageList = + TitleSpeed.ImageList = + TitleRange.ImageList = + Rarity.ImageList = + Fuel.ImageList = + Ammo.ImageList = + TitleBuildingTime.ImageList = + MaterialFuel.ImageList = + MaterialAmmo.ImageList = + MaterialSteel.ImageList = + MaterialBauxite.ImageList = + PowerUpFirepower.ImageList = + PowerUpTorpedo.ImageList = + PowerUpAA.ImageList = + PowerUpArmor.ImageList = + RemodelBeforeLevel.ImageList = + RemodelBeforeAmmo.ImageList = + RemodelBeforeSteel.ImageList = + RemodelAfterLevel.ImageList = + RemodelAfterAmmo.ImageList = + RemodelAfterSteel.ImageList = + ResourceManager.Instance.Icons; + + TitleAirSuperiority.ImageList = + TitleDayAttack.ImageList = + TitleNightAttack.ImageList = + Equipment1.ImageList = + Equipment2.ImageList = + Equipment3.ImageList = + Equipment4.ImageList = + Equipment5.ImageList = + ResourceManager.Instance.Equipments; + + TitleHP.ImageIndex = (int)ResourceManager.IconContent.ParameterHP; + TitleFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; + TitleTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; + TitleAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; + TitleArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; + TitleASW.ImageIndex = (int)ResourceManager.IconContent.ParameterASW; + TitleEvasion.ImageIndex = (int)ResourceManager.IconContent.ParameterEvasion; + TitleLOS.ImageIndex = (int)ResourceManager.IconContent.ParameterLOS; + TitleLuck.ImageIndex = (int)ResourceManager.IconContent.ParameterLuck; + TitleSpeed.ImageIndex = (int)ResourceManager.IconContent.ParameterSpeed; + TitleRange.ImageIndex = (int)ResourceManager.IconContent.ParameterRange; + Fuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; + Ammo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + TitleBuildingTime.ImageIndex = (int)ResourceManager.IconContent.FormArsenal; + MaterialFuel.ImageIndex = (int)ResourceManager.IconContent.ResourceFuel; + MaterialAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + MaterialSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; + MaterialBauxite.ImageIndex = (int)ResourceManager.IconContent.ResourceBauxite; + PowerUpFirepower.ImageIndex = (int)ResourceManager.IconContent.ParameterFirepower; + PowerUpTorpedo.ImageIndex = (int)ResourceManager.IconContent.ParameterTorpedo; + PowerUpAA.ImageIndex = (int)ResourceManager.IconContent.ParameterAA; + PowerUpArmor.ImageIndex = (int)ResourceManager.IconContent.ParameterArmor; + RemodelBeforeAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + RemodelBeforeSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; + RemodelAfterAmmo.ImageIndex = (int)ResourceManager.IconContent.ResourceAmmo; + RemodelAfterSteel.ImageIndex = (int)ResourceManager.IconContent.ResourceSteel; + TitleAirSuperiority.ImageIndex = (int)ResourceManager.EquipmentContent.CarrierBasedFighter; + TitleDayAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Seaplane; + TitleNightAttack.ImageIndex = (int)ResourceManager.EquipmentContent.Torpedo; - ParameterLevel.Value = ParameterLevel.Maximum = ExpTable.ShipMaximumLevel; - - - TableBattle.Visible = false; - BasePanelShipGirl.Visible = false; - - - ControlHelper.SetDoubleBuffered(TableShipName); - ControlHelper.SetDoubleBuffered(TableParameterMain); - ControlHelper.SetDoubleBuffered(TableParameterSub); - ControlHelper.SetDoubleBuffered(TableConsumption); - ControlHelper.SetDoubleBuffered(TableEquipment); - ControlHelper.SetDoubleBuffered(TableArsenal); - ControlHelper.SetDoubleBuffered(TableRemodel); - ControlHelper.SetDoubleBuffered(TableBattle); - - ControlHelper.SetDoubleBuffered(ShipView); - - - //ShipView Initialize - ShipView.SuspendLayout(); - - ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; - ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; - - - ShipView.Rows.Clear(); - - List rows = new List(KCDatabase.Instance.MasterShips.Values.Count(s => s.Name != "なし")); - - foreach (var ship in KCDatabase.Instance.MasterShips.Values) - { - - if (ship.Name == "なし") continue; - - DataGridViewRow row = new DataGridViewRow(); - row.CreateCells(ShipView); - row.SetValues(ship.ShipID, ship.ShipTypeName, ship.NameWithClass); - row.Cells[ShipView_ShipType.Index].Tag = ship.ShipType; - row.Cells[ShipView_Name.Index].Tag = ship.IsAbyssalShip ? null : ship.NameReading; - rows.Add(row); - - } - ShipView.Rows.AddRange(rows.ToArray()); + ParameterLevel.Value = ParameterLevel.Maximum = ExpTable.ShipMaximumLevel; + + + TableBattle.Visible = false; + BasePanelShipGirl.Visible = false; + + + ControlHelper.SetDoubleBuffered(TableShipName); + ControlHelper.SetDoubleBuffered(TableParameterMain); + ControlHelper.SetDoubleBuffered(TableParameterSub); + ControlHelper.SetDoubleBuffered(TableConsumption); + ControlHelper.SetDoubleBuffered(TableEquipment); + ControlHelper.SetDoubleBuffered(TableArsenal); + ControlHelper.SetDoubleBuffered(TableRemodel); + ControlHelper.SetDoubleBuffered(TableBattle); + + ControlHelper.SetDoubleBuffered(ShipView); + + + //ShipView Initialize + ShipView.SuspendLayout(); + + ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; + ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; + + + ShipView.Rows.Clear(); + + List rows = new List(KCDatabase.Instance.MasterShips.Values.Count(s => s.Name != "なし")); + + foreach (var ship in KCDatabase.Instance.MasterShips.Values) + { + + if (ship.Name == "なし") continue; + + DataGridViewRow row = new DataGridViewRow(); + row.CreateCells(ShipView); + row.SetValues(ship.ShipID, ship.ShipTypeName, ship.NameWithClass); + row.Cells[ShipView_ShipType.Index].Tag = ship.ShipType; + row.Cells[ShipView_Name.Index].Tag = ship.IsAbyssalShip ? null : ship.NameReading; + rows.Add(row); + + } + ShipView.Rows.AddRange(rows.ToArray()); - ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; - ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; + ShipView_ShipID.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; + ShipView_ShipType.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; - ShipView.Sort(ShipView_ShipID, ListSortDirection.Ascending); - ShipView.ResumeLayout(); - } + ShipView.Sort(ShipView_ShipID, ListSortDirection.Ascending); + ShipView.ResumeLayout(); + } - public DialogAlbumMasterShip(int shipID) - : this() - { + public DialogAlbumMasterShip(int shipID) + : this() + { - UpdateAlbumPage(shipID); + UpdateAlbumPage(shipID); - if (KCDatabase.Instance.MasterShips.ContainsKey(shipID)) - { - var row = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == shipID); - if (row != null) - ShipView.FirstDisplayedScrollingRowIndex = row.Index; - } + if (KCDatabase.Instance.MasterShips.ContainsKey(shipID)) + { + var row = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == shipID); + if (row != null) + ShipView.FirstDisplayedScrollingRowIndex = row.Index; + } - } + } - private void DialogAlbumMasterShip_Load(object sender, EventArgs e) - { + private void DialogAlbumMasterShip_Load(object sender, EventArgs e) + { - this.Icon = ResourceManager.ImageToIcon(ResourceManager.Instance.Icons.Images[(int)ResourceManager.IconContent.FormAlbumShip]); + this.Icon = ResourceManager.ImageToIcon(ResourceManager.Instance.Icons.Images[(int)ResourceManager.IconContent.FormAlbumShip]); - } + } - private void ShipView_SortCompare(object sender, DataGridViewSortCompareEventArgs e) - { + private void ShipView_SortCompare(object sender, DataGridViewSortCompareEventArgs e) + { - if (e.Column.Index == ShipView_ShipType.Index) - { - e.SortResult = (int)ShipView[e.Column.Index, e.RowIndex1].Tag - (int)ShipView[e.Column.Index, e.RowIndex2].Tag; + if (e.Column.Index == ShipView_ShipType.Index) + { + e.SortResult = (int)ShipView[e.Column.Index, e.RowIndex1].Tag - (int)ShipView[e.Column.Index, e.RowIndex2].Tag; - } - else if (e.Column.Index == ShipView_Name.Index) - { + } + else if (e.Column.Index == ShipView_Name.Index) + { - // 艦娘優先; 艦娘同士なら読みで比べる、深海棲艦同士なら名前で比べる + // 艦娘優先; 艦娘同士なら読みで比べる、深海棲艦同士なら名前で比べる - string tag1 = ShipView[e.Column.Index, e.RowIndex1].Tag as string; - string tag2 = ShipView[e.Column.Index, e.RowIndex2].Tag as string; + string tag1 = ShipView[e.Column.Index, e.RowIndex1].Tag as string; + string tag2 = ShipView[e.Column.Index, e.RowIndex2].Tag as string; - if (tag1 != null) - { - if (tag2 != null) - e.SortResult = tag1.CompareTo(tag2); - else - e.SortResult = -1; - } - else - { - if (tag2 != null) - e.SortResult = 1; - else - e.SortResult = 0; - } + if (tag1 != null) + { + if (tag2 != null) + e.SortResult = tag1.CompareTo(tag2); + else + e.SortResult = -1; + } + else + { + if (tag2 != null) + e.SortResult = 1; + else + e.SortResult = 0; + } - if (e.SortResult == 0) - e.SortResult = ((string)e.CellValue1).CompareTo(e.CellValue2); + if (e.SortResult == 0) + e.SortResult = ((string)e.CellValue1).CompareTo(e.CellValue2); - } - else - { - e.SortResult = ((IComparable)e.CellValue1).CompareTo(e.CellValue2); - } + } + else + { + e.SortResult = ((IComparable)e.CellValue1).CompareTo(e.CellValue2); + } - if (e.SortResult == 0) - { - e.SortResult = (int)(ShipView.Rows[e.RowIndex1].Tag ?? 0) - (int)(ShipView.Rows[e.RowIndex2].Tag ?? 0); - } + if (e.SortResult == 0) + { + e.SortResult = (int)(ShipView.Rows[e.RowIndex1].Tag ?? 0) - (int)(ShipView.Rows[e.RowIndex2].Tag ?? 0); + } - e.Handled = true; - } + e.Handled = true; + } - private void ShipView_Sorted(object sender, EventArgs e) - { + private void ShipView_Sorted(object sender, EventArgs e) + { - for (int i = 0; i < ShipView.Rows.Count; i++) - { - ShipView.Rows[i].Tag = i; - } + for (int i = 0; i < ShipView.Rows.Count; i++) + { + ShipView.Rows[i].Tag = i; + } - } + } - private void ShipView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) - { + private void ShipView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) + { - if (e.RowIndex >= 0) - { - int shipID = (int)ShipView.Rows[e.RowIndex].Cells[0].Value; + if (e.RowIndex >= 0) + { + int shipID = (int)ShipView.Rows[e.RowIndex].Cells[0].Value; - if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) - { - Cursor = Cursors.AppStarting; - new DialogAlbumMasterShip(shipID).Show(Owner); - Cursor = Cursors.Default; + if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) + { + Cursor = Cursors.AppStarting; + new DialogAlbumMasterShip(shipID).Show(Owner); + Cursor = Cursors.Default; - } - else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) - { - UpdateAlbumPage(shipID); - } - } + } + else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) + { + UpdateAlbumPage(shipID); + } + } - } + } - private void UpdateAlbumPage(int shipID) - { + private void UpdateAlbumPage(int shipID) + { - KCDatabase db = KCDatabase.Instance; - ShipDataMaster ship = db.MasterShips[shipID]; + KCDatabase db = KCDatabase.Instance; + ShipDataMaster ship = db.MasterShips[shipID]; - if (ship == null) return; + if (ship == null) return; - BasePanelShipGirl.SuspendLayout(); + BasePanelShipGirl.SuspendLayout(); - //header - TableShipName.SuspendLayout(); - _shipID = shipID; - ShipID.Text = ship.ShipID.ToString(); - AlbumNo.Text = ship.AlbumNo.ToString(); + //header + TableShipName.SuspendLayout(); + _shipID = shipID; + ShipID.Text = ship.ShipID.ToString(); + AlbumNo.Text = ship.AlbumNo.ToString(); - ResourceName.Text = $"{ship.ResourceName} {ship.ResourceGraphicVersion}/{ship.ResourceVoiceVersion}/{ship.ResourcePortVoiceVersion}"; - ToolTipInfo.SetToolTip(ResourceName, string.Format("リソース名: {0}\r\nグラフィック ver. {1}\r\nボイス ver. {2}\r\n母港ボイス ver. {3}\r\n({4})", - ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, Constants.GetVoiceFlag(ship.VoiceFlag))); + ResourceName.Text = $"{ship.ResourceName} {ship.ResourceGraphicVersion}/{ship.ResourceVoiceVersion}/{ship.ResourcePortVoiceVersion}"; + ToolTipInfo.SetToolTip(ResourceName, string.Format("リソース名: {0}\r\nグラフィック ver. {1}\r\nボイス ver. {2}\r\n母港ボイス ver. {3}\r\n({4})", + ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, Constants.GetVoiceFlag(ship.VoiceFlag))); - ShipType.Text = ship.IsLandBase ? "陸上施設" : ship.ShipTypeName; - ToolTipInfo.SetToolTip(ShipType, Constants.GetShipClass(ship.ShipClass)); - ShipName.Text = ship.NameWithClass; - ShipName.ForeColor = ship.GetShipNameColor(); - ToolTipInfo.SetToolTip(ShipName, (!ship.IsAbyssalShip ? ship.NameReading + "\r\n" : "") + "(右クリックでコピー)"); - TableShipName.ResumeLayout(); + ShipType.Text = ship.IsLandBase ? "陸上施設" : ship.ShipTypeName; + ToolTipInfo.SetToolTip(ShipType, Constants.GetShipClass(ship.ShipClass)); + ShipName.Text = ship.NameWithClass; + ShipName.ForeColor = ship.GetShipNameColor(); + ToolTipInfo.SetToolTip(ShipName, (!ship.IsAbyssalShip ? ship.NameReading + "\r\n" : "") + "(右クリックでコピー)"); + TableShipName.ResumeLayout(); - //main parameter - TableParameterMain.SuspendLayout(); + //main parameter + TableParameterMain.SuspendLayout(); - if (!ship.IsAbyssalShip) - { + if (!ship.IsAbyssalShip) + { - TitleParameterMin.Text = "初期値"; - TitleParameterMax.Text = "最大値"; + TitleParameterMin.Text = "初期値"; + TitleParameterMax.Text = "最大値"; - HPMin.Text = ship.HPMin.ToString(); - HPMax.Text = ship.HPMaxMarried.ToString(); - ToolTipInfo.SetToolTip(HPMin, string.Format("改修後: {0} (+{1})", ship.HPMaxModernized, ship.HPMaxModernizable)); - ToolTipInfo.SetToolTip(HPMax, string.Format("改修後: {0} (+{1})\r\n(内部最大耐久: {2})", ship.HPMaxMarriedModernized, ship.HPMaxMarriedModernizable, ship.HPMax)); + HPMin.Text = ship.HPMin.ToString(); + HPMax.Text = ship.HPMaxMarried.ToString(); + ToolTipInfo.SetToolTip(HPMin, string.Format("改修後: {0} (+{1})", ship.HPMaxModernized, ship.HPMaxModernizable)); + ToolTipInfo.SetToolTip(HPMax, string.Format("改修後: {0} (+{1})\r\n(内部最大耐久: {2})", ship.HPMaxMarriedModernized, ship.HPMaxMarriedModernizable, ship.HPMax)); - FirepowerMin.Text = ship.FirepowerMin.ToString(); - FirepowerMax.Text = ship.FirepowerMax.ToString(); + FirepowerMin.Text = ship.FirepowerMin.ToString(); + FirepowerMax.Text = ship.FirepowerMax.ToString(); - TorpedoMin.Text = ship.TorpedoMin.ToString(); - TorpedoMax.Text = ship.TorpedoMax.ToString(); + TorpedoMin.Text = ship.TorpedoMin.ToString(); + TorpedoMax.Text = ship.TorpedoMax.ToString(); - AAMin.Text = ship.AAMin.ToString(); - AAMax.Text = ship.AAMax.ToString(); + AAMin.Text = ship.AAMin.ToString(); + AAMax.Text = ship.AAMax.ToString(); - ArmorMin.Text = ship.ArmorMin.ToString(); - ArmorMax.Text = ship.ArmorMax.ToString(); + ArmorMin.Text = ship.ArmorMin.ToString(); + ArmorMax.Text = ship.ArmorMax.ToString(); - ASWMin.Text = GetParameterMinBound(ship.ASW); - ASWMax.Text = GetParameterMax(ship.ASW); + ASWMin.Text = GetParameterMinBound(ship.ASW); + ASWMax.Text = GetParameterMax(ship.ASW); - EvasionMin.Text = GetParameterMinBound(ship.Evasion); - EvasionMax.Text = GetParameterMax(ship.Evasion); + EvasionMin.Text = GetParameterMinBound(ship.Evasion); + EvasionMax.Text = GetParameterMax(ship.Evasion); - LOSMin.Text = GetParameterMinBound(ship.LOS); - LOSMax.Text = GetParameterMax(ship.LOS); + LOSMin.Text = GetParameterMinBound(ship.LOS); + LOSMax.Text = GetParameterMax(ship.LOS); - LuckMin.Text = ship.LuckMin.ToString(); - LuckMax.Text = ship.LuckMax.ToString(); + LuckMin.Text = ship.LuckMin.ToString(); + LuckMax.Text = ship.LuckMax.ToString(); - } - else - { + } + else + { - int hp = ship.HPMin; - int firepower = ship.FirepowerMax; - int torpedo = ship.TorpedoMax; - int aa = ship.AAMax; - int armor = ship.ArmorMax; - int asw = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum : 0; - int evasion = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum : 0; - int los = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum : 0; - int luck = ship.LuckMax; + int hp = ship.HPMin; + int firepower = ship.FirepowerMax; + int torpedo = ship.TorpedoMax; + int aa = ship.AAMax; + int armor = ship.ArmorMax; + int asw = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum : 0; + int evasion = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum : 0; + int los = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum : 0; + int luck = ship.LuckMax; - if (ship.DefaultSlot != null) - { - int count = ship.DefaultSlot.Count; - for (int i = 0; i < count; i++) - { - EquipmentDataMaster eq = KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[i]]; - if (eq == null) continue; + if (ship.DefaultSlot != null) + { + int count = ship.DefaultSlot.Count; + for (int i = 0; i < count; i++) + { + EquipmentDataMaster eq = KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[i]]; + if (eq == null) continue; - firepower += eq.Firepower; - torpedo += eq.Torpedo; - aa += eq.AA; - armor += eq.Armor; - asw += eq.ASW; - evasion += eq.Evasion; - los += eq.LOS; - luck += eq.Luck; - } - } + firepower += eq.Firepower; + torpedo += eq.Torpedo; + aa += eq.AA; + armor += eq.Armor; + asw += eq.ASW; + evasion += eq.Evasion; + los += eq.LOS; + luck += eq.Luck; + } + } - TitleParameterMin.Text = "基本値"; - TitleParameterMax.Text = "装備込"; + TitleParameterMin.Text = "基本値"; + TitleParameterMax.Text = "装備込"; - HPMin.Text = ship.HPMin > 0 ? ship.HPMin.ToString() : "???"; - HPMax.Text = hp > 0 ? hp.ToString() : "???"; - ToolTipInfo.SetToolTip(HPMin, null); - ToolTipInfo.SetToolTip(HPMax, null); + HPMin.Text = ship.HPMin > 0 ? ship.HPMin.ToString() : "???"; + HPMax.Text = hp > 0 ? hp.ToString() : "???"; + ToolTipInfo.SetToolTip(HPMin, null); + ToolTipInfo.SetToolTip(HPMax, null); - FirepowerMin.Text = ship.FirepowerMax.ToString(); - FirepowerMax.Text = firepower.ToString(); + FirepowerMin.Text = ship.FirepowerMax.ToString(); + FirepowerMax.Text = firepower.ToString(); - TorpedoMin.Text = ship.TorpedoMax.ToString(); - TorpedoMax.Text = torpedo.ToString(); - - AAMin.Text = ship.AAMax.ToString(); - AAMax.Text = aa.ToString(); - - ArmorMin.Text = ship.ArmorMax.ToString(); - ArmorMax.Text = armor.ToString(); - - ASWMin.Text = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum.ToString() : "???"; - ASWMax.Text = asw.ToString(); - - EvasionMin.Text = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum.ToString() : "???"; - EvasionMax.Text = evasion.ToString(); - - LOSMin.Text = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum.ToString() : "???"; - LOSMax.Text = los.ToString(); - - LuckMin.Text = ship.LuckMax > 0 ? ship.LuckMax.ToString() : "???"; - LuckMax.Text = luck > 0 ? luck.ToString() : "???"; - - } - UpdateLevelParameter(ship.ShipID); - - TableParameterMain.ResumeLayout(); - - - //sub parameter - TableParameterSub.SuspendLayout(); - - Speed.Text = Constants.GetSpeed(ship.Speed); - if (!ship.IsAbyssalShip) - { - Range.Text = Constants.GetRange(ship.Range); - ToolTipInfo.SetToolTip(Range, null); - } - else - { - var availableEquipments = (ship.DefaultSlot ?? Enumerable.Repeat(-1, 5)) - .Select(id => KCDatabase.Instance.MasterEquipments[id]) - .Where(eq => eq != null); - Range.Text = Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0)); - ToolTipInfo.SetToolTip(Range, "素の射程: " + Constants.GetRange(ship.Range)); - } - Rarity.Text = Constants.GetShipRarity(ship.Rarity); - Rarity.ImageIndex = (int)ResourceManager.IconContent.RarityRed + ship.Rarity; - - TableParameterSub.ResumeLayout(); - - TableConsumption.SuspendLayout(); - - Fuel.Text = ship.Fuel.ToString(); - Ammo.Text = ship.Ammo.ToString(); - - string tooltiptext = string.Format( - "入渠時の消費:\r\nHP1あたり: 鋼 {0:F2} / 燃 {1:F2}\r\n最大: 鋼 {2} / 燃 {3}\r\n", - (ship.Fuel * 0.06), - (ship.Fuel * 0.032), - (int)(ship.Fuel * 0.06 * (ship.HPMaxMarried - 1)), - (int)(ship.Fuel * 0.032 * (ship.HPMaxMarried - 1)) - ); - - ToolTipInfo.SetToolTip(TableConsumption, tooltiptext); - ToolTipInfo.SetToolTip(TitleConsumption, tooltiptext); - ToolTipInfo.SetToolTip(Fuel, tooltiptext); - ToolTipInfo.SetToolTip(Ammo, tooltiptext); - - TableConsumption.ResumeLayout(); - - Description.Text = ship.MessageAlbum != "" ? ship.MessageAlbum : ship.MessageGet; - Description.Tag = ship.MessageAlbum != "" ? 1 : 0; - - - //equipment - TableEquipment.SuspendLayout(); - - for (int i = 0; i < Equipments.Length; i++) - { - - if (ship.Aircraft[i] > 0 || i < ship.SlotSize) - Aircrafts[i].Text = ship.Aircraft[i].ToString(); - else - Aircrafts[i].Text = ""; - - - ToolTipInfo.SetToolTip(Equipments[i], null); - - if (ship.DefaultSlot == null) - { - if (i < ship.SlotSize) - { - Equipments[i].Text = "???"; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Unknown; - } - else - { - Equipments[i].Text = ""; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; - } - - } - else if (ship.DefaultSlot[i] != -1) - { - EquipmentDataMaster eq = db.MasterEquipments[ship.DefaultSlot[i]]; - if (eq == null) - { - // 破損データが入っていた場合 - Equipments[i].Text = "(なし)"; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; - - } - else - { - - Equipments[i].Text = eq.Name; - - int eqicon = eq.EquipmentType[3]; - if (eqicon >= (int)ResourceManager.EquipmentContent.Locked) - eqicon = (int)ResourceManager.EquipmentContent.Unknown; - - Equipments[i].ImageIndex = eqicon; - - { - StringBuilder sb = new StringBuilder(); - - sb.AppendFormat("{0} {1} (ID: {2})\r\n", eq.CategoryTypeInstance.Name, eq.Name, eq.EquipmentID); - if (eq.Firepower != 0) sb.AppendFormat("火力 {0:+0;-0}\r\n", eq.Firepower); - if (eq.Torpedo != 0) sb.AppendFormat("雷装 {0:+0;-0}\r\n", eq.Torpedo); - if (eq.AA != 0) sb.AppendFormat("対空 {0:+0;-0}\r\n", eq.AA); - if (eq.Armor != 0) sb.AppendFormat("装甲 {0:+0;-0}\r\n", eq.Armor); - if (eq.ASW != 0) sb.AppendFormat("対潜 {0:+0;-0}\r\n", eq.ASW); - if (eq.Evasion != 0) sb.AppendFormat("回避 {0:+0;-0}\r\n", eq.Evasion); - if (eq.LOS != 0) sb.AppendFormat("索敵 {0:+0;-0}\r\n", eq.LOS); - if (eq.Accuracy != 0) sb.AppendFormat("命中 {0:+0;-0}\r\n", eq.Accuracy); - if (eq.Bomber != 0) sb.AppendFormat("爆装 {0:+0;-0}\r\n", eq.Bomber); - sb.AppendLine("(右クリックで図鑑)"); - - ToolTipInfo.SetToolTip(Equipments[i], sb.ToString()); - } - } - - } - else if (i < ship.SlotSize) - { - Equipments[i].Text = "(なし)"; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; - - } - else - { - Equipments[i].Text = ""; - Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; - } - } - - TableEquipment.ResumeLayout(); - - - //arsenal - TableArsenal.SuspendLayout(); - BuildingTime.Text = DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)); - - MaterialFuel.Text = ship.Material[0].ToString(); - MaterialAmmo.Text = ship.Material[1].ToString(); - MaterialSteel.Text = ship.Material[2].ToString(); - MaterialBauxite.Text = ship.Material[3].ToString(); - - PowerUpFirepower.Text = ship.PowerUp[0].ToString(); - PowerUpTorpedo.Text = ship.PowerUp[1].ToString(); - PowerUpAA.Text = ship.PowerUp[2].ToString(); - PowerUpArmor.Text = ship.PowerUp[3].ToString(); - - TableArsenal.ResumeLayout(); - - - //remodel - if (!ship.IsAbyssalShip) - { - - TableRemodel.SuspendLayout(); - - if (ship.RemodelBeforeShipID == 0) - { - RemodelBeforeShipName.Text = "(なし)"; - ToolTipInfo.SetToolTip(RemodelBeforeShipName, null); - RemodelBeforeLevel.Text = ""; - RemodelBeforeLevel.ImageIndex = -1; - ToolTipInfo.SetToolTip(RemodelBeforeLevel, null); - RemodelBeforeAmmo.Text = "-"; - RemodelBeforeSteel.Text = "-"; - } - else - { - ShipDataMaster sbefore = ship.RemodelBeforeShip; - RemodelBeforeShipName.Text = sbefore.Name; - ToolTipInfo.SetToolTip(RemodelBeforeShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); - RemodelBeforeLevel.Text = string.Format("Lv. {0}", sbefore.RemodelAfterLevel); - RemodelBeforeLevel.ImageIndex = GetRemodelItemImageIndex(sbefore); - ToolTipInfo.SetToolTip(RemodelBeforeLevel, GetRemodelItem(sbefore)); - RemodelBeforeAmmo.Text = sbefore.RemodelAmmo.ToString(); - RemodelBeforeSteel.Text = sbefore.RemodelSteel.ToString(); - } - - if (ship.RemodelAfterShipID == 0) - { - RemodelAfterShipName.Text = "(なし)"; - ToolTipInfo.SetToolTip(RemodelAfterShipName, null); - RemodelAfterLevel.Text = ""; - RemodelAfterLevel.ImageIndex = -1; - ToolTipInfo.SetToolTip(RemodelAfterLevel, null); - RemodelAfterAmmo.Text = "-"; - RemodelAfterSteel.Text = "-"; - } - else - { - RemodelAfterShipName.Text = ship.RemodelAfterShip.Name; - ToolTipInfo.SetToolTip(RemodelAfterShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); - RemodelAfterLevel.Text = string.Format("Lv. {0}", ship.RemodelAfterLevel); - RemodelAfterLevel.ImageIndex = GetRemodelItemImageIndex(ship); - ToolTipInfo.SetToolTip(RemodelAfterLevel, GetRemodelItem(ship)); - RemodelAfterAmmo.Text = ship.RemodelAmmo.ToString(); - RemodelAfterSteel.Text = ship.RemodelSteel.ToString(); - } - TableRemodel.ResumeLayout(); - - - TableRemodel.Visible = true; - TableBattle.Visible = false; - - - } - else - { - - TableBattle.SuspendLayout(); - - AirSuperiority.Text = Calculator.GetAirSuperiority(ship).ToString(); - DayAttack.Text = Constants.GetDayAttackKind(Calculator.GetDayAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); - NightAttack.Text = Constants.GetNightAttackKind(Calculator.GetNightAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); - - TableBattle.ResumeLayout(); - - TableRemodel.Visible = false; - TableBattle.Visible = true; - - } - - - if (ShipBanner.Image != null) - { - var img = ShipBanner.Image; - ShipBanner.Image = null; - img.Dispose(); - } - if (!ImageLoader.IsBusy) - { - loadingResourceShipID = ship.ShipID; - ImageLoader.RunWorkerAsync(ship.ResourceName); - } - - - - BasePanelShipGirl.ResumeLayout(); - BasePanelShipGirl.Visible = true; - - - this.Text = "艦船図鑑 - " + ship.NameWithClass; - - } - - - private void UpdateLevelParameter(int shipID) - { - - ShipDataMaster ship = KCDatabase.Instance.MasterShips[shipID]; - - if (ship == null) - return; - - if (!ship.IsAbyssalShip) - { - ASWLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.ASW); - EvasionLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.Evasion); - LOSLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.LOS); - ASWLevel.Visible = - ASWSeparater.Visible = - EvasionLevel.Visible = - EvasionSeparater.Visible = - LOSLevel.Visible = - LOSSeparater.Visible = true; - - } - else - { - ASWLevel.Visible = - ASWSeparater.Visible = - EvasionLevel.Visible = - EvasionSeparater.Visible = - LOSLevel.Visible = - LOSSeparater.Visible = false; - } - } + TorpedoMin.Text = ship.TorpedoMax.ToString(); + TorpedoMax.Text = torpedo.ToString(); + + AAMin.Text = ship.AAMax.ToString(); + AAMax.Text = aa.ToString(); + + ArmorMin.Text = ship.ArmorMax.ToString(); + ArmorMax.Text = armor.ToString(); + + ASWMin.Text = ship.ASW != null && ship.ASW.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.ASW.Maximum.ToString() : "???"; + ASWMax.Text = asw.ToString(); + + EvasionMin.Text = ship.Evasion != null && ship.Evasion.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.Evasion.Maximum.ToString() : "???"; + EvasionMax.Text = evasion.ToString(); + + LOSMin.Text = ship.LOS != null && ship.LOS.Maximum != ShipParameterRecord.Parameter.MaximumDefault ? ship.LOS.Maximum.ToString() : "???"; + LOSMax.Text = los.ToString(); + + LuckMin.Text = ship.LuckMax > 0 ? ship.LuckMax.ToString() : "???"; + LuckMax.Text = luck > 0 ? luck.ToString() : "???"; + + } + UpdateLevelParameter(ship.ShipID); + + TableParameterMain.ResumeLayout(); + + + //sub parameter + TableParameterSub.SuspendLayout(); + + Speed.Text = Constants.GetSpeed(ship.Speed); + if (!ship.IsAbyssalShip) + { + Range.Text = Constants.GetRange(ship.Range); + ToolTipInfo.SetToolTip(Range, null); + } + else + { + var availableEquipments = (ship.DefaultSlot ?? Enumerable.Repeat(-1, 5)) + .Select(id => KCDatabase.Instance.MasterEquipments[id]) + .Where(eq => eq != null); + Range.Text = Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0)); + ToolTipInfo.SetToolTip(Range, "素の射程: " + Constants.GetRange(ship.Range)); + } + Rarity.Text = Constants.GetShipRarity(ship.Rarity); + Rarity.ImageIndex = (int)ResourceManager.IconContent.RarityRed + ship.Rarity; + + TableParameterSub.ResumeLayout(); + + TableConsumption.SuspendLayout(); + + Fuel.Text = ship.Fuel.ToString(); + Ammo.Text = ship.Ammo.ToString(); + + string tooltiptext = string.Format( + "入渠時の消費:\r\nHP1あたり: 鋼 {0:F2} / 燃 {1:F2}\r\n最大: 鋼 {2} / 燃 {3}\r\n", + (ship.Fuel * 0.06), + (ship.Fuel * 0.032), + (int)(ship.Fuel * 0.06 * (ship.HPMaxMarried - 1)), + (int)(ship.Fuel * 0.032 * (ship.HPMaxMarried - 1)) + ); + + ToolTipInfo.SetToolTip(TableConsumption, tooltiptext); + ToolTipInfo.SetToolTip(TitleConsumption, tooltiptext); + ToolTipInfo.SetToolTip(Fuel, tooltiptext); + ToolTipInfo.SetToolTip(Ammo, tooltiptext); + + TableConsumption.ResumeLayout(); + + Description.Text = ship.MessageAlbum != "" ? ship.MessageAlbum : ship.MessageGet; + Description.Tag = ship.MessageAlbum != "" ? 1 : 0; + + + //equipment + TableEquipment.SuspendLayout(); + + for (int i = 0; i < Equipments.Length; i++) + { + + if (ship.Aircraft[i] > 0 || i < ship.SlotSize) + Aircrafts[i].Text = ship.Aircraft[i].ToString(); + else + Aircrafts[i].Text = ""; + + + ToolTipInfo.SetToolTip(Equipments[i], null); + + if (ship.DefaultSlot == null) + { + if (i < ship.SlotSize) + { + Equipments[i].Text = "???"; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Unknown; + } + else + { + Equipments[i].Text = ""; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; + } + + } + else if (ship.DefaultSlot[i] != -1) + { + EquipmentDataMaster eq = db.MasterEquipments[ship.DefaultSlot[i]]; + if (eq == null) + { + // 破損データが入っていた場合 + Equipments[i].Text = "(なし)"; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; + + } + else + { + + Equipments[i].Text = eq.Name; + + int eqicon = eq.EquipmentType[3]; + if (eqicon >= (int)ResourceManager.EquipmentContent.Locked) + eqicon = (int)ResourceManager.EquipmentContent.Unknown; + + Equipments[i].ImageIndex = eqicon; + + { + StringBuilder sb = new StringBuilder(); + + sb.AppendFormat("{0} {1} (ID: {2})\r\n", eq.CategoryTypeInstance.Name, eq.Name, eq.EquipmentID); + if (eq.Firepower != 0) sb.AppendFormat("火力 {0:+0;-0}\r\n", eq.Firepower); + if (eq.Torpedo != 0) sb.AppendFormat("雷装 {0:+0;-0}\r\n", eq.Torpedo); + if (eq.AA != 0) sb.AppendFormat("対空 {0:+0;-0}\r\n", eq.AA); + if (eq.Armor != 0) sb.AppendFormat("装甲 {0:+0;-0}\r\n", eq.Armor); + if (eq.ASW != 0) sb.AppendFormat("対潜 {0:+0;-0}\r\n", eq.ASW); + if (eq.Evasion != 0) sb.AppendFormat("回避 {0:+0;-0}\r\n", eq.Evasion); + if (eq.LOS != 0) sb.AppendFormat("索敵 {0:+0;-0}\r\n", eq.LOS); + if (eq.Accuracy != 0) sb.AppendFormat("命中 {0:+0;-0}\r\n", eq.Accuracy); + if (eq.Bomber != 0) sb.AppendFormat("爆装 {0:+0;-0}\r\n", eq.Bomber); + sb.AppendLine("(右クリックで図鑑)"); + + ToolTipInfo.SetToolTip(Equipments[i], sb.ToString()); + } + } + + } + else if (i < ship.SlotSize) + { + Equipments[i].Text = "(なし)"; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Nothing; + + } + else + { + Equipments[i].Text = ""; + Equipments[i].ImageIndex = (int)ResourceManager.EquipmentContent.Locked; + } + } + + TableEquipment.ResumeLayout(); + + + //arsenal + TableArsenal.SuspendLayout(); + BuildingTime.Text = DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)); + + MaterialFuel.Text = ship.Material[0].ToString(); + MaterialAmmo.Text = ship.Material[1].ToString(); + MaterialSteel.Text = ship.Material[2].ToString(); + MaterialBauxite.Text = ship.Material[3].ToString(); + + PowerUpFirepower.Text = ship.PowerUp[0].ToString(); + PowerUpTorpedo.Text = ship.PowerUp[1].ToString(); + PowerUpAA.Text = ship.PowerUp[2].ToString(); + PowerUpArmor.Text = ship.PowerUp[3].ToString(); + + TableArsenal.ResumeLayout(); + + + //remodel + if (!ship.IsAbyssalShip) + { + + TableRemodel.SuspendLayout(); + + if (ship.RemodelBeforeShipID == 0) + { + RemodelBeforeShipName.Text = "(なし)"; + ToolTipInfo.SetToolTip(RemodelBeforeShipName, null); + RemodelBeforeLevel.Text = ""; + RemodelBeforeLevel.ImageIndex = -1; + ToolTipInfo.SetToolTip(RemodelBeforeLevel, null); + RemodelBeforeAmmo.Text = "-"; + RemodelBeforeSteel.Text = "-"; + } + else + { + ShipDataMaster sbefore = ship.RemodelBeforeShip; + RemodelBeforeShipName.Text = sbefore.Name; + ToolTipInfo.SetToolTip(RemodelBeforeShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); + RemodelBeforeLevel.Text = string.Format("Lv. {0}", sbefore.RemodelAfterLevel); + RemodelBeforeLevel.ImageIndex = GetRemodelItemImageIndex(sbefore); + ToolTipInfo.SetToolTip(RemodelBeforeLevel, GetRemodelItem(sbefore)); + RemodelBeforeAmmo.Text = sbefore.RemodelAmmo.ToString(); + RemodelBeforeSteel.Text = sbefore.RemodelSteel.ToString(); + } + + if (ship.RemodelAfterShipID == 0) + { + RemodelAfterShipName.Text = "(なし)"; + ToolTipInfo.SetToolTip(RemodelAfterShipName, null); + RemodelAfterLevel.Text = ""; + RemodelAfterLevel.ImageIndex = -1; + ToolTipInfo.SetToolTip(RemodelAfterLevel, null); + RemodelAfterAmmo.Text = "-"; + RemodelAfterSteel.Text = "-"; + } + else + { + RemodelAfterShipName.Text = ship.RemodelAfterShip.Name; + ToolTipInfo.SetToolTip(RemodelAfterShipName, "(左クリックで開く, 右クリックで新規ウィンドウ)"); + RemodelAfterLevel.Text = string.Format("Lv. {0}", ship.RemodelAfterLevel); + RemodelAfterLevel.ImageIndex = GetRemodelItemImageIndex(ship); + ToolTipInfo.SetToolTip(RemodelAfterLevel, GetRemodelItem(ship)); + RemodelAfterAmmo.Text = ship.RemodelAmmo.ToString(); + RemodelAfterSteel.Text = ship.RemodelSteel.ToString(); + } + TableRemodel.ResumeLayout(); + + + TableRemodel.Visible = true; + TableBattle.Visible = false; + + + } + else + { + + TableBattle.SuspendLayout(); + + AirSuperiority.Text = Calculator.GetAirSuperiority(ship).ToString(); + DayAttack.Text = Constants.GetDayAttackKind(Calculator.GetDayAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); + NightAttack.Text = Constants.GetNightAttackKind(Calculator.GetNightAttackKind(ship.DefaultSlot?.ToArray(), ship.ShipID, -1)); + + TableBattle.ResumeLayout(); + + TableRemodel.Visible = false; + TableBattle.Visible = true; + + } + + + if (ShipBanner.Image != null) + { + var img = ShipBanner.Image; + ShipBanner.Image = null; + img.Dispose(); + } + if (!ImageLoader.IsBusy) + { + loadingResourceShipID = ship.ShipID; + ImageLoader.RunWorkerAsync(ship.ResourceName); + } + + + + BasePanelShipGirl.ResumeLayout(); + BasePanelShipGirl.Visible = true; + + + this.Text = "艦船図鑑 - " + ship.NameWithClass; + + } + + + private void UpdateLevelParameter(int shipID) + { + + ShipDataMaster ship = KCDatabase.Instance.MasterShips[shipID]; + + if (ship == null) + return; + + if (!ship.IsAbyssalShip) + { + ASWLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.ASW); + EvasionLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.Evasion); + LOSLevel.Text = EstimateParameter((int)ParameterLevel.Value, ship.LOS); + ASWLevel.Visible = + ASWSeparater.Visible = + EvasionLevel.Visible = + EvasionSeparater.Visible = + LOSLevel.Visible = + LOSSeparater.Visible = true; + + } + else + { + ASWLevel.Visible = + ASWSeparater.Visible = + EvasionLevel.Visible = + EvasionSeparater.Visible = + LOSLevel.Visible = + LOSSeparater.Visible = false; + } + } - private string EstimateParameter(int level, ShipParameterRecord.Parameter param) - { + private string EstimateParameter(int level, ShipParameterRecord.Parameter param) + { - if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) - return "???"; + if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) + return "???"; - int min = (int)(param.MinimumEstMin + (param.Maximum - param.MinimumEstMin) * level / 99.0); - int max = (int)(param.MinimumEstMax + (param.Maximum - param.MinimumEstMax) * level / 99.0); + int min = (int)(param.MinimumEstMin + (param.Maximum - param.MinimumEstMin) * level / 99.0); + int max = (int)(param.MinimumEstMax + (param.Maximum - param.MinimumEstMax) * level / 99.0); - if (min == max) - return min.ToString(); - else - return $"{Math.Min(min, max)}~{Math.Max(min, max)}"; - } + if (min == max) + return min.ToString(); + else + return $"{Math.Min(min, max)}~{Math.Max(min, max)}"; + } - private string GetParameterMinBound(ShipParameterRecord.Parameter param) - { + private string GetParameterMinBound(ShipParameterRecord.Parameter param) + { - if (param == null || param.MinimumEstMax == ShipParameterRecord.Parameter.MaximumDefault) - return "???"; - else if (param.MinimumEstMin == param.MinimumEstMax) - return param.MinimumEstMin.ToString(); - else if (param.MinimumEstMin == ShipParameterRecord.Parameter.MinimumDefault && param.MinimumEstMax == param.Maximum) - return "???"; - else - return $"{param.MinimumEstMin}~{param.MinimumEstMax}"; + if (param == null || param.MinimumEstMax == ShipParameterRecord.Parameter.MaximumDefault) + return "???"; + else if (param.MinimumEstMin == param.MinimumEstMax) + return param.MinimumEstMin.ToString(); + else if (param.MinimumEstMin == ShipParameterRecord.Parameter.MinimumDefault && param.MinimumEstMax == param.Maximum) + return "???"; + else + return $"{param.MinimumEstMin}~{param.MinimumEstMax}"; - } + } - private string GetParameterMax(ShipParameterRecord.Parameter param) - { + private string GetParameterMax(ShipParameterRecord.Parameter param) + { - if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) - return "???"; - else - return param.Maximum.ToString(); + if (param == null || param.Maximum == ShipParameterRecord.Parameter.MaximumDefault) + return "???"; + else + return param.Maximum.ToString(); - } + } - private void ParameterLevel_ValueChanged(object sender, EventArgs e) - { - if (_shipID != -1) - { - LevelTimer.Start(); - //UpdateLevelParameter( _shipID ); - } - } + private void ParameterLevel_ValueChanged(object sender, EventArgs e) + { + if (_shipID != -1) + { + LevelTimer.Start(); + //UpdateLevelParameter( _shipID ); + } + } - private void LevelTimer_Tick(object sender, EventArgs e) - { - if (_shipID != -1) - UpdateLevelParameter(_shipID); - } + private void LevelTimer_Tick(object sender, EventArgs e) + { + if (_shipID != -1) + UpdateLevelParameter(_shipID); + } - private void TableParameterMain_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - /*/ + private void TableParameterMain_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + /*/ if ( e.Column == 0 ) e.Graphics.DrawLine( Pens.Silver, e.CellBounds.Right - 1, e.CellBounds.Y, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1 ); //*/ - } + } - private void TableParameterSub_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableParameterSub_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableConsumption_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableConsumption_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableEquipment_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableEquipment_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableArsenal_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableArsenal_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void TableRemodel_CellPaint(object sender, TableLayoutCellPaintEventArgs e) - { - if (e.Row % 2 == 1) - e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); - } + private void TableRemodel_CellPaint(object sender, TableLayoutCellPaintEventArgs e) + { + if (e.Row % 2 == 1) + e.Graphics.DrawLine(Pens.Silver, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); + } - private void RemodelBeforeShipName_MouseClick(object sender, MouseEventArgs e) - { + private void RemodelBeforeShipName_MouseClick(object sender, MouseEventArgs e) + { - if (_shipID == -1) return; - var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (_shipID == -1) return; + var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null && ship.RemodelBeforeShipID != 0) - { + if (ship != null && ship.RemodelBeforeShipID != 0) + { - if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) - new DialogAlbumMasterShip(ship.RemodelBeforeShipID).Show(Owner); + if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) + new DialogAlbumMasterShip(ship.RemodelBeforeShipID).Show(Owner); - else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) - UpdateAlbumPage(ship.RemodelBeforeShipID); - } - } + else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) + UpdateAlbumPage(ship.RemodelBeforeShipID); + } + } - private void RemodelAfterShipName_MouseClick(object sender, MouseEventArgs e) - { + private void RemodelAfterShipName_MouseClick(object sender, MouseEventArgs e) + { - if (_shipID == -1) return; - var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (_shipID == -1) return; + var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null && ship.RemodelAfterShipID != 0) - { - - if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) - new DialogAlbumMasterShip(ship.RemodelAfterShipID).Show(Owner); - - else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) - UpdateAlbumPage(ship.RemodelAfterShipID); - } - } - - - - private void Equipment_MouseClick(object sender, MouseEventArgs e) - { - - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - - for (int i = 0; i < Equipments.Length; i++) - { - if (sender == Equipments[i]) - { - - if (_shipID != -1) - { - ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; - - if (ship != null && ship.DefaultSlot != null && i < ship.DefaultSlot.Count && KCDatabase.Instance.MasterEquipments.ContainsKey(ship.DefaultSlot[i])) - { - Cursor = Cursors.AppStarting; - new DialogAlbumMasterEquipment(ship.DefaultSlot[i]).Show(Owner); - Cursor = Cursors.Default; - } - } - } - } - - } - } - - - private static int GetRemodelItemImageIndex(ShipDataMaster ship) - { - return - ship.NeedCatapult > 0 ? (int)ResourceManager.IconContent.ItemCatapult : - ship.NeedActionReport > 0 ? (int)ResourceManager.IconContent.ItemActionReport : - ship.NeedBlueprint > 0 ? (int)ResourceManager.IconContent.ItemBlueprint : - -1; - } - - private static string GetRemodelItem(ShipDataMaster ship) - { - StringBuilder sb = new StringBuilder(); - if (ship.NeedBlueprint > 0) - sb.AppendLine("改装設計図: " + ship.NeedBlueprint); - if (ship.NeedCatapult > 0) - sb.AppendLine("試製甲板カタパルト: " + ship.NeedCatapult); - if (ship.NeedActionReport > 0) - sb.AppendLine("戦闘詳報: " + ship.NeedActionReport); - - return sb.ToString(); - } - - - private void StripMenu_File_OutputCSVUser_Click(object sender, EventArgs e) - { - - if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - - try - { - - using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) - { - - sw.WriteLine("艦船ID,図鑑番号,艦型,艦種,艦名,読み,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,戦闘詳報,改装段階,耐久初期,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期,対潜最大,回避初期,回避最大,索敵初期,索敵最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン"); - - foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) - { - - if (ship.Name == "なし") continue; - - sw.WriteLine(string.Join(",", - ship.ShipID, - ship.AlbumNo, - ship.IsAbyssalShip ? "深海棲艦" : Constants.GetShipClass(ship.ShipClass), - ship.ShipTypeName, - ship.Name, - ship.NameReading, - ship.RemodelBeforeShipID > 0 ? ship.RemodelBeforeShip.Name : "-", - ship.RemodelAfterShipID > 0 ? ship.RemodelAfterShip.Name : "-", - ship.RemodelAfterLevel, - ship.RemodelAmmo, - ship.RemodelSteel, - ship.NeedBlueprint > 0 ? ship.NeedBlueprint + "枚" : "-", - ship.NeedCatapult > 0 ? ship.NeedCatapult + "個" : "-", - ship.NeedActionReport > 0 ? ship.NeedActionReport + "枚" : "-", - ship.RemodelTier, - ship.HPMin, - ship.HPMaxMarried, - ship.FirepowerMin, - ship.FirepowerMax, - ship.TorpedoMin, - ship.TorpedoMax, - ship.AAMin, - ship.AAMax, - ship.ArmorMin, - ship.ArmorMax, - ship.ASW != null && !ship.ASW.IsMinimumDefault ? ship.ASW.Minimum.ToString() : "???", - ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum.ToString() : "???", - ship.Evasion != null && !ship.Evasion.IsMinimumDefault ? ship.Evasion.Minimum.ToString() : "???", - ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum.ToString() : "???", - ship.LOS != null && !ship.LOS.IsMinimumDefault ? ship.LOS.Minimum.ToString() : "???", - ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum.ToString() : "???", - ship.LuckMin, - ship.LuckMax, - Constants.GetSpeed(ship.Speed), - Constants.GetRange(ship.Range), - Constants.GetShipRarity(ship.Rarity), - ship.SlotSize, - ship.Aircraft[0], - ship.Aircraft[1], - ship.Aircraft[2], - ship.Aircraft[3], - ship.Aircraft[4], - ship.DefaultSlot != null ? (ship.DefaultSlot[0] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[0]].Name : (ship.SlotSize > 0 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[1] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[1]].Name : (ship.SlotSize > 1 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[2] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[2]].Name : (ship.SlotSize > 2 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[3] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[3]].Name : (ship.SlotSize > 3 ? "(なし)" : "")) : "???", - ship.DefaultSlot != null ? (ship.DefaultSlot[4] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[4]].Name : (ship.SlotSize > 4 ? "(なし)" : "")) : "???", - DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)), - ship.Material[0], - ship.Material[1], - ship.Material[2], - ship.Material[3], - ship.PowerUp[0], - ship.PowerUp[1], - ship.PowerUp[2], - ship.PowerUp[3], - ship.MessageGet.Replace("\r\n", "
"), - ship.MessageAlbum.Replace("\r\n", "
"), - ship.Fuel, - ship.Ammo, - Constants.GetVoiceFlag(ship.VoiceFlag), - ship.ResourceName, - ship.ResourceGraphicVersion, - ship.ResourceVoiceVersion, - ship.ResourcePortVoiceVersion - )); - - } - - } - - } - catch (Exception ex) - { - - Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); - MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - - } - - } - - - private void StripMenu_File_OutputCSVData_Click(object sender, EventArgs e) - { - - if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) - { - - try - { - - using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) - { - - sw.WriteLine(string.Format("艦船ID,図鑑番号,艦名,読み,艦種,艦型,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,戦闘詳報,改装段階,耐久初期,耐久最大,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期最小,対潜初期最大,対潜最大,対潜{0}最小,対潜{0}最大,回避初期最小,回避初期最大,回避最大,回避{0}最小,回避{0}最大,索敵初期最小,索敵初期最大,索敵最大,索敵{0}最小,索敵{0}最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン", ExpTable.ShipMaximumLevel)); - - foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) - { - - sw.WriteLine(string.Join(",", - ship.ShipID, - ship.AlbumNo, - ship.Name, - ship.NameReading, - (int)ship.ShipType, - ship.ShipClass, - ship.RemodelBeforeShipID, - ship.RemodelAfterShipID, - ship.RemodelAfterLevel, - ship.RemodelAmmo, - ship.RemodelSteel, - ship.NeedBlueprint, - ship.NeedCatapult, - ship.NeedActionReport, - ship.RemodelTier, - ship.HPMin, - ship.HPMax, - ship.HPMaxMarried, - ship.FirepowerMin, - ship.FirepowerMax, - ship.TorpedoMin, - ship.TorpedoMax, - ship.AAMin, - ship.AAMax, - ship.ArmorMin, - ship.ArmorMax, - ship.ASW?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.ASW?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.ASW?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.ASW?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.ASW?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.Evasion?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.Evasion?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.Evasion?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.Evasion?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.Evasion?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LOS?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.LOS?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LOS?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LOS?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, - ship.LOS?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, - ship.LuckMin, - ship.LuckMax, - ship.Speed, - ship.Range, - ship.Rarity, - ship.SlotSize, - ship.Aircraft[0], - ship.Aircraft[1], - ship.Aircraft[2], - ship.Aircraft[3], - ship.Aircraft[4], - ship.DefaultSlot?[0] ?? -1, - ship.DefaultSlot?[1] ?? -1, - ship.DefaultSlot?[2] ?? -1, - ship.DefaultSlot?[3] ?? -1, - ship.DefaultSlot?[4] ?? -1, - ship.BuildingTime, - ship.Material[0], - ship.Material[1], - ship.Material[2], - ship.Material[3], - ship.PowerUp[0], - ship.PowerUp[1], - ship.PowerUp[2], - ship.PowerUp[3], - ship.MessageGet.Replace("\r\n", "
"), - ship.MessageAlbum.Replace("\r\n", "
"), - ship.Fuel, - ship.Ammo, - ship.VoiceFlag, - ship.ResourceName, - ship.ResourceGraphicVersion, - ship.ResourceVoiceVersion, - ship.ResourcePortVoiceVersion - )); - - } - - } - - } - catch (Exception ex) - { - - Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); - MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - - } - - } - - - - private void DialogAlbumMasterShip_FormClosed(object sender, FormClosedEventArgs e) - { - - ResourceManager.DestroyIcon(Icon); - - } - - - - private void Description_Click(object sender, EventArgs e) - { - - int tag = Description.Tag as int? ?? 0; - ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; - - if (ship == null) return; - - if (tag == 0 && ship.MessageAlbum.Length > 0) - { - Description.Text = ship.MessageAlbum; - Description.Tag = 1; - - } - else - { - Description.Text = ship.MessageGet; - Description.Tag = 0; - } - } - - - private void ResourceName_MouseClick(object sender, MouseEventArgs e) - { - - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - { - Clipboard.SetData(DataFormats.StringFormat, ship.ResourceName); - } - } + if (ship != null && ship.RemodelAfterShipID != 0) + { + + if ((e.Button & System.Windows.Forms.MouseButtons.Right) != 0) + new DialogAlbumMasterShip(ship.RemodelAfterShipID).Show(Owner); + + else if ((e.Button & System.Windows.Forms.MouseButtons.Left) != 0) + UpdateAlbumPage(ship.RemodelAfterShipID); + } + } + + + + private void Equipment_MouseClick(object sender, MouseEventArgs e) + { + + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + + for (int i = 0; i < Equipments.Length; i++) + { + if (sender == Equipments[i]) + { + + if (_shipID != -1) + { + ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; + + if (ship != null && ship.DefaultSlot != null && i < ship.DefaultSlot.Count && KCDatabase.Instance.MasterEquipments.ContainsKey(ship.DefaultSlot[i])) + { + Cursor = Cursors.AppStarting; + new DialogAlbumMasterEquipment(ship.DefaultSlot[i]).Show(Owner); + Cursor = Cursors.Default; + } + } + } + } + + } + } + + + private static int GetRemodelItemImageIndex(ShipDataMaster ship) + { + return + ship.NeedCatapult > 0 ? (int)ResourceManager.IconContent.ItemCatapult : + ship.NeedActionReport > 0 ? (int)ResourceManager.IconContent.ItemActionReport : + ship.NeedBlueprint > 0 ? (int)ResourceManager.IconContent.ItemBlueprint : + -1; + } + + private static string GetRemodelItem(ShipDataMaster ship) + { + StringBuilder sb = new StringBuilder(); + if (ship.NeedBlueprint > 0) + sb.AppendLine("改装設計図: " + ship.NeedBlueprint); + if (ship.NeedCatapult > 0) + sb.AppendLine("試製甲板カタパルト: " + ship.NeedCatapult); + if (ship.NeedActionReport > 0) + sb.AppendLine("戦闘詳報: " + ship.NeedActionReport); + + return sb.ToString(); + } + + + private void StripMenu_File_OutputCSVUser_Click(object sender, EventArgs e) + { + + if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + + try + { + + using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) + { + + sw.WriteLine("艦船ID,図鑑番号,艦型,艦種,艦名,読み,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,戦闘詳報,改装段階,耐久初期,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期,対潜最大,回避初期,回避最大,索敵初期,索敵最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン"); + + foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) + { + + if (ship.Name == "なし") continue; + + sw.WriteLine(string.Join(",", + ship.ShipID, + ship.AlbumNo, + ship.IsAbyssalShip ? "深海棲艦" : Constants.GetShipClass(ship.ShipClass), + ship.ShipTypeName, + ship.Name, + ship.NameReading, + ship.RemodelBeforeShipID > 0 ? ship.RemodelBeforeShip.Name : "-", + ship.RemodelAfterShipID > 0 ? ship.RemodelAfterShip.Name : "-", + ship.RemodelAfterLevel, + ship.RemodelAmmo, + ship.RemodelSteel, + ship.NeedBlueprint > 0 ? ship.NeedBlueprint + "枚" : "-", + ship.NeedCatapult > 0 ? ship.NeedCatapult + "個" : "-", + ship.NeedActionReport > 0 ? ship.NeedActionReport + "枚" : "-", + ship.RemodelTier, + ship.HPMin, + ship.HPMaxMarried, + ship.FirepowerMin, + ship.FirepowerMax, + ship.TorpedoMin, + ship.TorpedoMax, + ship.AAMin, + ship.AAMax, + ship.ArmorMin, + ship.ArmorMax, + ship.ASW != null && !ship.ASW.IsMinimumDefault ? ship.ASW.Minimum.ToString() : "???", + ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum.ToString() : "???", + ship.Evasion != null && !ship.Evasion.IsMinimumDefault ? ship.Evasion.Minimum.ToString() : "???", + ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum.ToString() : "???", + ship.LOS != null && !ship.LOS.IsMinimumDefault ? ship.LOS.Minimum.ToString() : "???", + ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum.ToString() : "???", + ship.LuckMin, + ship.LuckMax, + Constants.GetSpeed(ship.Speed), + Constants.GetRange(ship.Range), + Constants.GetShipRarity(ship.Rarity), + ship.SlotSize, + ship.Aircraft[0], + ship.Aircraft[1], + ship.Aircraft[2], + ship.Aircraft[3], + ship.Aircraft[4], + ship.DefaultSlot != null ? (ship.DefaultSlot[0] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[0]].Name : (ship.SlotSize > 0 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[1] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[1]].Name : (ship.SlotSize > 1 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[2] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[2]].Name : (ship.SlotSize > 2 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[3] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[3]].Name : (ship.SlotSize > 3 ? "(なし)" : "")) : "???", + ship.DefaultSlot != null ? (ship.DefaultSlot[4] != -1 ? KCDatabase.Instance.MasterEquipments[ship.DefaultSlot[4]].Name : (ship.SlotSize > 4 ? "(なし)" : "")) : "???", + DateTimeHelper.ToTimeRemainString(new TimeSpan(0, ship.BuildingTime, 0)), + ship.Material[0], + ship.Material[1], + ship.Material[2], + ship.Material[3], + ship.PowerUp[0], + ship.PowerUp[1], + ship.PowerUp[2], + ship.PowerUp[3], + ship.MessageGet.Replace("\r\n", "
"), + ship.MessageAlbum.Replace("\r\n", "
"), + ship.Fuel, + ship.Ammo, + Constants.GetVoiceFlag(ship.VoiceFlag), + ship.ResourceName, + ship.ResourceGraphicVersion, + ship.ResourceVoiceVersion, + ship.ResourcePortVoiceVersion + )); + + } + + } + + } + catch (Exception ex) + { + + Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); + MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + } + + + private void StripMenu_File_OutputCSVData_Click(object sender, EventArgs e) + { + + if (SaveCSVDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + + try + { + + using (StreamWriter sw = new StreamWriter(SaveCSVDialog.FileName, false, Utility.Configuration.Config.Log.FileEncoding)) + { + + sw.WriteLine(string.Format("艦船ID,図鑑番号,艦名,読み,艦種,艦型,改装前,改装後,改装Lv,改装弾薬,改装鋼材,改装設計図,カタパルト,戦闘詳報,改装段階,耐久初期,耐久最大,耐久結婚,火力初期,火力最大,雷装初期,雷装最大,対空初期,対空最大,装甲初期,装甲最大,対潜初期最小,対潜初期最大,対潜最大,対潜{0}最小,対潜{0}最大,回避初期最小,回避初期最大,回避最大,回避{0}最小,回避{0}最大,索敵初期最小,索敵初期最大,索敵最大,索敵{0}最小,索敵{0}最大,運初期,運最大,速力,射程,レア,スロット数,搭載機数1,搭載機数2,搭載機数3,搭載機数4,搭載機数5,初期装備1,初期装備2,初期装備3,初期装備4,初期装備5,建造時間,解体燃料,解体弾薬,解体鋼材,解体ボーキ,改修火力,改修雷装,改修対空,改修装甲,ドロップ文章,図鑑文章,搭載燃料,搭載弾薬,ボイス,リソース名,画像バージョン,ボイスバージョン,母港ボイスバージョン", ExpTable.ShipMaximumLevel)); + + foreach (ShipDataMaster ship in KCDatabase.Instance.MasterShips.Values) + { + + sw.WriteLine(string.Join(",", + ship.ShipID, + ship.AlbumNo, + ship.Name, + ship.NameReading, + (int)ship.ShipType, + ship.ShipClass, + ship.RemodelBeforeShipID, + ship.RemodelAfterShipID, + ship.RemodelAfterLevel, + ship.RemodelAmmo, + ship.RemodelSteel, + ship.NeedBlueprint, + ship.NeedCatapult, + ship.NeedActionReport, + ship.RemodelTier, + ship.HPMin, + ship.HPMax, + ship.HPMaxMarried, + ship.FirepowerMin, + ship.FirepowerMax, + ship.TorpedoMin, + ship.TorpedoMax, + ship.AAMin, + ship.AAMax, + ship.ArmorMin, + ship.ArmorMax, + ship.ASW?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.ASW?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.ASW?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.ASW?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.ASW?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.Evasion?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.Evasion?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.Evasion?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.Evasion?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.Evasion?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LOS?.MinimumEstMin ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.LOS?.MinimumEstMax ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LOS?.Maximum ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LOS?.GetEstParameterMin(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MinimumDefault, + ship.LOS?.GetEstParameterMax(ExpTable.ShipMaximumLevel) ?? ShipParameterRecord.Parameter.MaximumDefault, + ship.LuckMin, + ship.LuckMax, + ship.Speed, + ship.Range, + ship.Rarity, + ship.SlotSize, + ship.Aircraft[0], + ship.Aircraft[1], + ship.Aircraft[2], + ship.Aircraft[3], + ship.Aircraft[4], + ship.DefaultSlot?[0] ?? -1, + ship.DefaultSlot?[1] ?? -1, + ship.DefaultSlot?[2] ?? -1, + ship.DefaultSlot?[3] ?? -1, + ship.DefaultSlot?[4] ?? -1, + ship.BuildingTime, + ship.Material[0], + ship.Material[1], + ship.Material[2], + ship.Material[3], + ship.PowerUp[0], + ship.PowerUp[1], + ship.PowerUp[2], + ship.PowerUp[3], + ship.MessageGet.Replace("\r\n", "
"), + ship.MessageAlbum.Replace("\r\n", "
"), + ship.Fuel, + ship.Ammo, + ship.VoiceFlag, + ship.ResourceName, + ship.ResourceGraphicVersion, + ship.ResourceVoiceVersion, + ship.ResourcePortVoiceVersion + )); + + } + + } + + } + catch (Exception ex) + { + + Utility.ErrorReporter.SendErrorReport(ex, "艦船図鑑 CSVの出力に失敗しました。"); + MessageBox.Show("艦船図鑑 CSVの出力に失敗しました。\r\n" + ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + } + + } + + + + private void DialogAlbumMasterShip_FormClosed(object sender, FormClosedEventArgs e) + { + + ResourceManager.DestroyIcon(Icon); + + } + + + + private void Description_Click(object sender, EventArgs e) + { + + int tag = Description.Tag as int? ?? 0; + ShipDataMaster ship = KCDatabase.Instance.MasterShips[_shipID]; + + if (ship == null) return; + + if (tag == 0 && ship.MessageAlbum.Length > 0) + { + Description.Text = ship.MessageAlbum; + Description.Tag = 1; + + } + else + { + Description.Text = ship.MessageGet; + Description.Tag = 0; + } + } + + + private void ResourceName_MouseClick(object sender, MouseEventArgs e) + { + + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + { + Clipboard.SetData(DataFormats.StringFormat, ship.ResourceName); + } + } - } + } - private void StripMenu_Edit_EditParameter_Click(object sender, EventArgs e) - { + private void StripMenu_Edit_EditParameter_Click(object sender, EventArgs e) + { - if (_shipID <= 0) - { - MessageBox.Show("艦船を選択してください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); - return; - } + if (_shipID <= 0) + { + MessageBox.Show("艦船を選択してください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + return; + } - using (var dialog = new DialogAlbumShipParameter(_shipID)) - { - dialog.ShowDialog(this); - UpdateAlbumPage(_shipID); - } + using (var dialog = new DialogAlbumShipParameter(_shipID)) + { + dialog.ShowDialog(this); + UpdateAlbumPage(_shipID); + } - } + } - private void ImageLoader_DoWork(object sender, DoWorkEventArgs e) - { + private void ImageLoader_DoWork(object sender, DoWorkEventArgs e) + { - string resourceName = e.Argument as string; + string resourceName = e.Argument as string; - //System.Threading.Thread.Sleep( 2000 ); // for test + //System.Threading.Thread.Sleep( 2000 ); // for test - try - { + try + { - var img = SwfHelper.GetShipSwfImage(resourceName, SwfHelper.ShipResourceCharacterID.BannerNormal); + var img = SwfHelper.GetShipSwfImage(resourceName, SwfHelper.ShipResourceCharacterID.BannerNormal); - if (img.Size == SwfHelper.ShipBannerSize) - { - e.Result = img; - } - else - { - img.Dispose(); - e.Result = null; - } - } - catch (Exception) - { - e.Result = null; - } + if (img.Size == SwfHelper.ShipBannerSize) + { + e.Result = img; + } + else + { + img.Dispose(); + e.Result = null; + } + } + catch (Exception) + { + e.Result = null; + } - } + } - private void ImageLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { + private void ImageLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { - if (ShipBanner.Image != null) - { - var img = ShipBanner.Image; - ShipBanner.Image = null; - img.Dispose(); - } - - if (loadingResourceShipID != _shipID) - { - if (e.Result != null) - ((Bitmap)e.Result).Dispose(); - - if (!ImageLoader.IsBusy) - { - loadingResourceShipID = _shipID; - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - ImageLoader.RunWorkerAsync(ship.ResourceName); - } - - return; - } - - if (e.Result != null) - { - ShipBanner.Image = e.Result as Bitmap; - loadingResourceShipID = -1; - } - - } - - - - private void TextSearch_TextChanged(object sender, EventArgs e) - { - - if (string.IsNullOrWhiteSpace(TextSearch.Text)) - return; - - string searchWord = ToHiragana(TextSearch.Text.ToLower()); - var target = - ShipView.Rows.OfType() - .Select(r => KCDatabase.Instance.MasterShips[(int)r.Cells[ShipView_ShipID.Index].Value]) - .FirstOrDefault( - ship => - ToHiragana(ship.NameWithClass.ToLower()).StartsWith(searchWord) || - ToHiragana(ship.NameReading.ToLower()).StartsWith(searchWord)); - - if (target != null) - { - ShipView.FirstDisplayedScrollingRowIndex = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == target.ShipID).Index; - } - } - - public static string ToHiragana(string str) - { - // あまり深いことは考えずにやる - char hiraganaHead = '\x3041'; - char katakanaHead = '\x30a1'; - char katakanaTail = '\x30ff'; - - char[] chars = str.ToCharArray(); - for (int i = 0; i < chars.Length; i++) - { - if (katakanaHead <= chars[i] && chars[i] <= katakanaTail) - { // is katakana - chars[i] = (char)((int)chars[i] - (int)katakanaHead + (int)hiraganaHead); - } - } - - return new string(chars); - } - - private void TextSearch_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode == Keys.Enter) - { - TextSearch_TextChanged(sender, e); - e.SuppressKeyPress = true; - e.Handled = true; - } - } - - private void StripMenu_Edit_CopyShipName_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - Clipboard.SetText(ship.NameWithClass); - else - System.Media.SystemSounds.Exclamation.Play(); - } - - private void ShipName_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - Clipboard.SetText(ship.NameWithClass); - else - System.Media.SystemSounds.Exclamation.Play(); - } - } - - private void StripMenu_Edit_CopyShipData_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship == null) - { - System.Media.SystemSounds.Exclamation.Play(); - return; - } - - var sb = new StringBuilder(); - - var slot = (ship.DefaultSlot ?? Enumerable.Repeat(-2, 5)).ToArray(); - - sb.AppendFormat("{0} {1}\r\n", ship.ShipTypeName, ship.NameWithClass); - sb.AppendFormat("ID: {0} / 図鑑番号: {1} / リソース: {2} ver. {3} / {4} / {5} ({6})\r\n", ship.ShipID, ship.AlbumNo, - ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, - Constants.GetVoiceFlag(ship.VoiceFlag)); - sb.AppendLine(); - if (!ship.IsAbyssalShip) - { - sb.AppendFormat("耐久: {0} / {1}\r\n", ship.HPMin, ship.HPMaxMarried); - sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax); - sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax); - sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax); - sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax); - sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMinBound(ship.ASW), GetParameterMax(ship.ASW)); - sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMinBound(ship.Evasion), GetParameterMax(ship.Evasion)); - sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMinBound(ship.LOS), GetParameterMax(ship.LOS)); - sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin, ship.LuckMax); - sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), Constants.GetRange(ship.Range)); - sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); - sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); - } - else - { - var availableEquipments = slot.Select(id => KCDatabase.Instance.MasterEquipments[id]).Where(eq => eq != null); - int luckSum = ship.LuckMax + availableEquipments.Sum(eq => eq.Luck); - sb.AppendFormat("耐久: {0}\r\n", ship.HPMin > 0 ? ship.HPMin.ToString() : "???"); - sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax + availableEquipments.Sum(eq => eq.Firepower)); - sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax + availableEquipments.Sum(eq => eq.Torpedo)); - sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax + availableEquipments.Sum(eq => eq.AA)); - sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax + availableEquipments.Sum(eq => eq.Armor)); - sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMax(ship.ASW), (ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum : 0) + availableEquipments.Sum(eq => eq.ASW)); - sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMax(ship.Evasion), (ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum : 0) + availableEquipments.Sum(eq => eq.Evasion)); - sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMax(ship.LOS), (ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum : 0) + availableEquipments.Sum(eq => eq.LOS)); - sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin > 0 ? ship.LuckMin.ToString() : "???", luckSum > 0 ? luckSum.ToString() : "???"); - sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), - Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0))); - if (ship.Fuel > 0 || ship.Ammo > 0) - sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); - if (ship.Rarity > 0) - sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); - } - sb.AppendLine(); - sb.AppendLine("初期装備:"); - { - for (int i = 0; i < slot.Length; i++) - { - string name; - var eq = KCDatabase.Instance.MasterEquipments[slot[i]]; - if (eq == null && i >= ship.SlotSize) - continue; - - if (eq != null) - name = eq.Name; - else if (slot[i] == -1) - name = "(なし)"; - else - name = "(不明)"; - - sb.AppendFormat("[{0}] {1}\r\n", ship.Aircraft[i], name); - } - } - sb.AppendLine(); - if (!ship.IsAbyssalShip) - { - sb.AppendFormat("建造時間: {0}\r\n", DateTimeHelper.ToTimeRemainString(TimeSpan.FromMinutes(ship.BuildingTime))); - sb.AppendFormat("解体資源: {0}\r\n", string.Join(" / ", ship.Material)); - sb.AppendFormat("改修強化: {0}\r\n", string.Join(" / ", ship.PowerUp)); - if (ship.RemodelBeforeShipID != 0) - { - var before = ship.RemodelBeforeShip; - var append = new List(4) - { - "弾薬 " + before.RemodelAmmo, - "鋼材 " + before.RemodelSteel - }; - if (before.NeedBlueprint > 0) - append.Add("要改装設計図"); - if (before.NeedCatapult > 0) - append.Add("要カタパルト"); - if (before.NeedActionReport > 0) - append.Add("要戦闘詳報"); - - sb.AppendFormat("改造前: {0} Lv. {1} ({2})\r\n", - before.NameWithClass, before.RemodelAfterLevel, string.Join(", ", append)); - } - else - { - sb.AppendLine("改造前: (なし)"); - } - if (ship.RemodelAfterShipID != 0) - { - var append = new List(4) - { - "弾薬 " + ship.RemodelAmmo, - "鋼材 " + ship.RemodelSteel - }; - if (ship.NeedBlueprint > 0) - append.Add("要改装設計図"); - if (ship.NeedCatapult > 0) - append.Add("要カタパルト"); - if (ship.NeedActionReport > 0) - append.Add("要戦闘詳報"); - - sb.AppendFormat("改造後: {0} Lv. {1} ({2})\r\n", - ship.RemodelAfterShip.NameWithClass, ship.RemodelAfterLevel, string.Join(", ", append)); - } - else - { - sb.AppendLine("改造後: (なし)"); - } - sb.AppendLine(); - sb.AppendFormat("図鑑文章: \r\n{0}\r\n\r\n入手文章: \r\n{1}\r\n\r\n", - !string.IsNullOrWhiteSpace(ship.MessageAlbum) ? ship.MessageAlbum : "(不明)", - !string.IsNullOrWhiteSpace(ship.MessageGet) ? ship.MessageGet : "(不明)"); - } - - sb.AppendLine("出現海域:"); - { - string result = GetAppearingArea(ship.ShipID); - if (string.IsNullOrEmpty(result)) - result = "(不明)"; - sb.AppendLine(result); - } - - Clipboard.SetText(sb.ToString()); - } - - - - private string GetAppearingArea(int shipID) - { - - var ship = KCDatabase.Instance.MasterShips[shipID]; - if (ship == null) - return string.Empty; - - var sb = new StringBuilder(); - - if (!ship.IsAbyssalShip) - { - - foreach (var record in RecordManager.Instance.ShipDrop.Record - .Where(s => s.ShipID == shipID && s.EnemyFleetID != 0) - .Select(s => new - { - s.MapAreaID, - s.MapInfoID, - s.CellID, - s.Difficulty, - EnemyFleetName = RecordManager.Instance.EnemyFleet.Record.ContainsKey(s.EnemyFleetID) ? - RecordManager.Instance.EnemyFleet.Record[s.EnemyFleetID].FleetName : "敵艦隊名不明" - }) - .Distinct() - .OrderBy(r => r.MapAreaID) - .ThenBy(r => r.MapInfoID) - .ThenBy(r => r.CellID) - .ThenBy(r => r.Difficulty) - ) - { - sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", - record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); - } - - foreach (var record in RecordManager.Instance.Construction.Record - .Where(s => s.ShipID == shipID) - .Select(s => new - { - s.Fuel, - s.Ammo, - s.Steel, - s.Bauxite, - s.DevelopmentMaterial - }) - .Distinct() - .OrderBy(r => r.Fuel) - .ThenBy(r => r.Ammo) - .ThenBy(r => r.Steel) - .ThenBy(r => r.Bauxite) - .ThenBy(r => r.DevelopmentMaterial) - ) - { - sb.AppendFormat("建造 {0} / {1} / {2} / {3} - {4}\r\n", - record.Fuel, record.Ammo, record.Steel, record.Bauxite, record.DevelopmentMaterial); - } - - } - else - { - - foreach (var record in RecordManager.Instance.EnemyFleet.Record.Values - .Where(r => r.FleetMember.Contains(shipID)) - .Select(s => new - { - s.MapAreaID, - s.MapInfoID, - s.CellID, - s.Difficulty, - EnemyFleetName = !string.IsNullOrWhiteSpace(s.FleetName) ? s.FleetName : "敵艦隊名不明" - }) - .Distinct() - .OrderBy(r => r.MapAreaID) - .ThenBy(r => r.MapInfoID) - .ThenBy(r => r.CellID) - .ThenBy(r => r.Difficulty) - ) - { - sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", - record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); - } - - } - - return sb.ToString(); - } - - private void StripMenu_View_ShowAppearingArea_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship == null) - { - System.Media.SystemSounds.Exclamation.Play(); - return; - } - - string result = GetAppearingArea(ship.ShipID); - - if (string.IsNullOrEmpty(result)) - result = ship.NameWithClass + " の出現海域は不明です。"; - - MessageBox.Show(result, "出現海域検索", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - - - private void ShipBanner_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == System.Windows.Forms.MouseButtons.Right) - { - - StripMenu_View_ShowShipGraphicViewer.PerformClick(); - } - } - - private void StripMenu_View_ShowShipGraphicViewer_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship != null) - { - - var pathlist = new LinkedList(); - pathlist.AddLast(SwfHelper.GetShipResourcePath(ship.ResourceName)); - - foreach (var rec in RecordManager.Instance.ShipParameter.Record.Values.Where(r => r.OriginalCostumeShipID == _shipID)) - { - string path = SwfHelper.GetShipResourcePath(rec.ResourceName); - if (path != null) - pathlist.AddLast(path); - } - - var arg = pathlist.Where(p => p != null).ToArray(); - if (arg.Length > 0) - { - new DialogShipGraphicViewer(arg).Show(Owner); - } - else - { - MessageBox.Show("画像リソースが存在しません。以下の手順を踏んでください。\r\n1. 設定→通信→通信内容を保存する 及び SWF を有効にする。\r\n2. キャッシュをクリアし、再読み込みする。\r\n3. 艦これ本体で当該艦を表示させる(図鑑画面を開くなど)。", "ビューア:画像リソース不足", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - } - else - { - MessageBox.Show("対象艦船を指定してください。", "ビューア:対象未指定", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - } - - - private void StripMenu_Edit_GoogleShipName_Click(object sender, EventArgs e) - { - var ship = KCDatabase.Instance.MasterShips[_shipID]; - if (ship == null) - { - System.Media.SystemSounds.Exclamation.Play(); - return; - } - - try - { - - // google <艦船名> 艦これ - System.Diagnostics.Process.Start(@"https://www.google.co.jp/search?q=" + Uri.EscapeDataString(ship.NameWithClass) + "+%E8%89%A6%E3%81%93%E3%82%8C"); - - } - catch (Exception ex) - { - Utility.ErrorReporter.SendErrorReport(ex, "艦船名の Google 検索に失敗しました。"); - } - } - - } + if (ShipBanner.Image != null) + { + var img = ShipBanner.Image; + ShipBanner.Image = null; + img.Dispose(); + } + + if (loadingResourceShipID != _shipID) + { + if (e.Result != null) + ((Bitmap)e.Result).Dispose(); + + if (!ImageLoader.IsBusy) + { + loadingResourceShipID = _shipID; + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + ImageLoader.RunWorkerAsync(ship.ResourceName); + } + + return; + } + + if (e.Result != null) + { + ShipBanner.Image = e.Result as Bitmap; + loadingResourceShipID = -1; + } + + } + + + + private void TextSearch_TextChanged(object sender, EventArgs e) + { + + if (string.IsNullOrWhiteSpace(TextSearch.Text)) + return; + + string searchWord = ToHiragana(TextSearch.Text.ToLower()); + var target = + ShipView.Rows.OfType() + .Select(r => KCDatabase.Instance.MasterShips[(int)r.Cells[ShipView_ShipID.Index].Value]) + .FirstOrDefault( + ship => + ToHiragana(ship.NameWithClass.ToLower()).StartsWith(searchWord) || + ToHiragana(ship.NameReading.ToLower()).StartsWith(searchWord)); + + if (target != null) + { + ShipView.FirstDisplayedScrollingRowIndex = ShipView.Rows.OfType().First(r => (int)r.Cells[ShipView_ShipID.Index].Value == target.ShipID).Index; + } + } + + public static string ToHiragana(string str) + { + // あまり深いことは考えずにやる + char hiraganaHead = '\x3041'; + char katakanaHead = '\x30a1'; + char katakanaTail = '\x30ff'; + + char[] chars = str.ToCharArray(); + for (int i = 0; i < chars.Length; i++) + { + if (katakanaHead <= chars[i] && chars[i] <= katakanaTail) + { // is katakana + chars[i] = (char)((int)chars[i] - (int)katakanaHead + (int)hiraganaHead); + } + } + + return new string(chars); + } + + private void TextSearch_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + TextSearch_TextChanged(sender, e); + e.SuppressKeyPress = true; + e.Handled = true; + } + } + + private void StripMenu_Edit_CopyShipName_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + Clipboard.SetText(ship.NameWithClass); + else + System.Media.SystemSounds.Exclamation.Play(); + } + + private void ShipName_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + Clipboard.SetText(ship.NameWithClass); + else + System.Media.SystemSounds.Exclamation.Play(); + } + } + + private void StripMenu_Edit_CopyShipData_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship == null) + { + System.Media.SystemSounds.Exclamation.Play(); + return; + } + + var sb = new StringBuilder(); + + var slot = (ship.DefaultSlot ?? Enumerable.Repeat(-2, 5)).ToArray(); + + sb.AppendFormat("{0} {1}\r\n", ship.ShipTypeName, ship.NameWithClass); + sb.AppendFormat("ID: {0} / 図鑑番号: {1} / リソース: {2} ver. {3} / {4} / {5} ({6})\r\n", ship.ShipID, ship.AlbumNo, + ship.ResourceName, ship.ResourceGraphicVersion, ship.ResourceVoiceVersion, ship.ResourcePortVoiceVersion, + Constants.GetVoiceFlag(ship.VoiceFlag)); + sb.AppendLine(); + if (!ship.IsAbyssalShip) + { + sb.AppendFormat("耐久: {0} / {1}\r\n", ship.HPMin, ship.HPMaxMarried); + sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax); + sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax); + sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax); + sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax); + sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMinBound(ship.ASW), GetParameterMax(ship.ASW)); + sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMinBound(ship.Evasion), GetParameterMax(ship.Evasion)); + sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMinBound(ship.LOS), GetParameterMax(ship.LOS)); + sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin, ship.LuckMax); + sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), Constants.GetRange(ship.Range)); + sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); + sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); + } + else + { + var availableEquipments = slot.Select(id => KCDatabase.Instance.MasterEquipments[id]).Where(eq => eq != null); + int luckSum = ship.LuckMax + availableEquipments.Sum(eq => eq.Luck); + sb.AppendFormat("耐久: {0}\r\n", ship.HPMin > 0 ? ship.HPMin.ToString() : "???"); + sb.AppendFormat("火力: {0} / {1}\r\n", ship.FirepowerMin, ship.FirepowerMax + availableEquipments.Sum(eq => eq.Firepower)); + sb.AppendFormat("雷装: {0} / {1}\r\n", ship.TorpedoMin, ship.TorpedoMax + availableEquipments.Sum(eq => eq.Torpedo)); + sb.AppendFormat("対空: {0} / {1}\r\n", ship.AAMin, ship.AAMax + availableEquipments.Sum(eq => eq.AA)); + sb.AppendFormat("装甲: {0} / {1}\r\n", ship.ArmorMin, ship.ArmorMax + availableEquipments.Sum(eq => eq.Armor)); + sb.AppendFormat("対潜: {0} / {1}\r\n", GetParameterMax(ship.ASW), (ship.ASW != null && !ship.ASW.IsMaximumDefault ? ship.ASW.Maximum : 0) + availableEquipments.Sum(eq => eq.ASW)); + sb.AppendFormat("回避: {0} / {1}\r\n", GetParameterMax(ship.Evasion), (ship.Evasion != null && !ship.Evasion.IsMaximumDefault ? ship.Evasion.Maximum : 0) + availableEquipments.Sum(eq => eq.Evasion)); + sb.AppendFormat("索敵: {0} / {1}\r\n", GetParameterMax(ship.LOS), (ship.LOS != null && !ship.LOS.IsMaximumDefault ? ship.LOS.Maximum : 0) + availableEquipments.Sum(eq => eq.LOS)); + sb.AppendFormat("運: {0} / {1}\r\n", ship.LuckMin > 0 ? ship.LuckMin.ToString() : "???", luckSum > 0 ? luckSum.ToString() : "???"); + sb.AppendFormat("速力: {0} / 射程: {1}\r\n", Constants.GetSpeed(ship.Speed), + Constants.GetRange(Math.Max(ship.Range, availableEquipments.Any() ? availableEquipments.Max(eq => eq.Range) : 0))); + if (ship.Fuel > 0 || ship.Ammo > 0) + sb.AppendFormat("搭載資源: 燃料 {0} / 弾薬 {1}\r\n", ship.Fuel, ship.Ammo); + if (ship.Rarity > 0) + sb.AppendFormat("レアリティ: {0}\r\n", Constants.GetShipRarity(ship.Rarity)); + } + sb.AppendLine(); + sb.AppendLine("初期装備:"); + { + for (int i = 0; i < slot.Length; i++) + { + string name; + var eq = KCDatabase.Instance.MasterEquipments[slot[i]]; + if (eq == null && i >= ship.SlotSize) + continue; + + if (eq != null) + name = eq.Name; + else if (slot[i] == -1) + name = "(なし)"; + else + name = "(不明)"; + + sb.AppendFormat("[{0}] {1}\r\n", ship.Aircraft[i], name); + } + } + sb.AppendLine(); + if (!ship.IsAbyssalShip) + { + sb.AppendFormat("建造時間: {0}\r\n", DateTimeHelper.ToTimeRemainString(TimeSpan.FromMinutes(ship.BuildingTime))); + sb.AppendFormat("解体資源: {0}\r\n", string.Join(" / ", ship.Material)); + sb.AppendFormat("改修強化: {0}\r\n", string.Join(" / ", ship.PowerUp)); + if (ship.RemodelBeforeShipID != 0) + { + var before = ship.RemodelBeforeShip; + var append = new List(4) + { + "弾薬 " + before.RemodelAmmo, + "鋼材 " + before.RemodelSteel + }; + if (before.NeedBlueprint > 0) + append.Add("要改装設計図"); + if (before.NeedCatapult > 0) + append.Add("要カタパルト"); + if (before.NeedActionReport > 0) + append.Add("要戦闘詳報"); + + sb.AppendFormat("改造前: {0} Lv. {1} ({2})\r\n", + before.NameWithClass, before.RemodelAfterLevel, string.Join(", ", append)); + } + else + { + sb.AppendLine("改造前: (なし)"); + } + if (ship.RemodelAfterShipID != 0) + { + var append = new List(4) + { + "弾薬 " + ship.RemodelAmmo, + "鋼材 " + ship.RemodelSteel + }; + if (ship.NeedBlueprint > 0) + append.Add("要改装設計図"); + if (ship.NeedCatapult > 0) + append.Add("要カタパルト"); + if (ship.NeedActionReport > 0) + append.Add("要戦闘詳報"); + + sb.AppendFormat("改造後: {0} Lv. {1} ({2})\r\n", + ship.RemodelAfterShip.NameWithClass, ship.RemodelAfterLevel, string.Join(", ", append)); + } + else + { + sb.AppendLine("改造後: (なし)"); + } + sb.AppendLine(); + sb.AppendFormat("図鑑文章: \r\n{0}\r\n\r\n入手文章: \r\n{1}\r\n\r\n", + !string.IsNullOrWhiteSpace(ship.MessageAlbum) ? ship.MessageAlbum : "(不明)", + !string.IsNullOrWhiteSpace(ship.MessageGet) ? ship.MessageGet : "(不明)"); + } + + sb.AppendLine("出現海域:"); + { + string result = GetAppearingArea(ship.ShipID); + if (string.IsNullOrEmpty(result)) + result = "(不明)"; + sb.AppendLine(result); + } + + Clipboard.SetText(sb.ToString()); + } + + + + private string GetAppearingArea(int shipID) + { + + var ship = KCDatabase.Instance.MasterShips[shipID]; + if (ship == null) + return string.Empty; + + var sb = new StringBuilder(); + + if (!ship.IsAbyssalShip) + { + + foreach (var record in RecordManager.Instance.ShipDrop.Record + .Where(s => s.ShipID == shipID && s.EnemyFleetID != 0) + .Select(s => new + { + s.MapAreaID, + s.MapInfoID, + s.CellID, + s.Difficulty, + EnemyFleetName = RecordManager.Instance.EnemyFleet.Record.ContainsKey(s.EnemyFleetID) ? + RecordManager.Instance.EnemyFleet.Record[s.EnemyFleetID].FleetName : "敵艦隊名不明" + }) + .Distinct() + .OrderBy(r => r.MapAreaID) + .ThenBy(r => r.MapInfoID) + .ThenBy(r => r.CellID) + .ThenBy(r => r.Difficulty) + ) + { + sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", + record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); + } + + foreach (var record in RecordManager.Instance.Construction.Record + .Where(s => s.ShipID == shipID) + .Select(s => new + { + s.Fuel, + s.Ammo, + s.Steel, + s.Bauxite, + s.DevelopmentMaterial + }) + .Distinct() + .OrderBy(r => r.Fuel) + .ThenBy(r => r.Ammo) + .ThenBy(r => r.Steel) + .ThenBy(r => r.Bauxite) + .ThenBy(r => r.DevelopmentMaterial) + ) + { + sb.AppendFormat("建造 {0} / {1} / {2} / {3} - {4}\r\n", + record.Fuel, record.Ammo, record.Steel, record.Bauxite, record.DevelopmentMaterial); + } + + } + else + { + + foreach (var record in RecordManager.Instance.EnemyFleet.Record.Values + .Where(r => r.FleetMember.Contains(shipID)) + .Select(s => new + { + s.MapAreaID, + s.MapInfoID, + s.CellID, + s.Difficulty, + EnemyFleetName = !string.IsNullOrWhiteSpace(s.FleetName) ? s.FleetName : "敵艦隊名不明" + }) + .Distinct() + .OrderBy(r => r.MapAreaID) + .ThenBy(r => r.MapInfoID) + .ThenBy(r => r.CellID) + .ThenBy(r => r.Difficulty) + ) + { + sb.AppendFormat("{0}-{1}-{2}{3} ({4})\r\n", + record.MapAreaID, record.MapInfoID, record.CellID, record.Difficulty > 0 ? " [" + Constants.GetDifficulty(record.Difficulty) + "]" : "", record.EnemyFleetName); + } + + } + + return sb.ToString(); + } + + private void StripMenu_View_ShowAppearingArea_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship == null) + { + System.Media.SystemSounds.Exclamation.Play(); + return; + } + + string result = GetAppearingArea(ship.ShipID); + + if (string.IsNullOrEmpty(result)) + result = ship.NameWithClass + " の出現海域は不明です。"; + + MessageBox.Show(result, "出現海域検索", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + + + private void ShipBanner_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == System.Windows.Forms.MouseButtons.Right) + { + + StripMenu_View_ShowShipGraphicViewer.PerformClick(); + } + } + + private void StripMenu_View_ShowShipGraphicViewer_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship != null) + { + + var pathlist = new LinkedList(); + pathlist.AddLast(SwfHelper.GetShipResourcePath(ship.ResourceName)); + + foreach (var rec in RecordManager.Instance.ShipParameter.Record.Values.Where(r => r.OriginalCostumeShipID == _shipID)) + { + string path = SwfHelper.GetShipResourcePath(rec.ResourceName); + if (path != null) + pathlist.AddLast(path); + } + + var arg = pathlist.Where(p => p != null).ToArray(); + if (arg.Length > 0) + { + new DialogShipGraphicViewer(arg).Show(Owner); + } + else + { + MessageBox.Show("画像リソースが存在しません。以下の手順を踏んでください。\r\n1. 設定→通信→通信内容を保存する 及び SWF を有効にする。\r\n2. キャッシュをクリアし、再読み込みする。\r\n3. 艦これ本体で当該艦を表示させる(図鑑画面を開くなど)。", "ビューア:画像リソース不足", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + else + { + MessageBox.Show("対象艦船を指定してください。", "ビューア:対象未指定", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + + + private void StripMenu_Edit_GoogleShipName_Click(object sender, EventArgs e) + { + var ship = KCDatabase.Instance.MasterShips[_shipID]; + if (ship == null) + { + System.Media.SystemSounds.Exclamation.Play(); + return; + } + + try + { + + // google <艦船名> 艦これ + System.Diagnostics.Process.Start(@"https://www.google.co.jp/search?q=" + Uri.EscapeDataString(ship.NameWithClass) + "+%E8%89%A6%E3%81%93%E3%82%8C"); + + } + catch (Exception ex) + { + Utility.ErrorReporter.SendErrorReport(ex, "艦船名の Google 検索に失敗しました。"); + } + } + + } } From 06ae0a4151f900ab2ef229e14e2c3fe704af2f5f Mon Sep 17 00:00:00 2001 From: RadarNyan Date: Sat, 30 Dec 2017 00:35:52 +0900 Subject: [PATCH 08/12] =?UTF-8?q?=E5=AF=BE=E7=A9=BA=E7=A0=B2=E7=81=AB?= =?UTF-8?q?=E8=A9=B3=E7=B4=B0=EF=BC=9A=E6=95=B5=E3=82=B9=E3=83=AD=E3=83=83?= =?UTF-8?q?=E3=83=88=E6=A9=9F=E6=95=B0=E7=9B=B4=E6=8E=A5=E5=85=A5=E5=8A=9B?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=81=A8=E8=90=BD=E3=81=A1=E3=82=8B=E4=B8=8D?= =?UTF-8?q?=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * また、敵スロット機数の最小値を0から1に変更 --- .../Window/Dialog/DialogAntiAirDefense.Designer.cs | 5 +++++ ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.Designer.cs b/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.Designer.cs index a05553c16..c7cb43a05 100644 --- a/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.Designer.cs +++ b/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.Designer.cs @@ -204,6 +204,11 @@ private void InitializeComponent() 0, 0, 0}); + this.EnemySlotCount.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); this.EnemySlotCount.Name = "EnemySlotCount"; this.EnemySlotCount.Size = new System.Drawing.Size(80, 23); this.EnemySlotCount.TabIndex = 2; diff --git a/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs b/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs index 88c23299a..bcb2bf087 100644 --- a/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs +++ b/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs @@ -55,9 +55,12 @@ public static implicit operator int(FormationComboBoxData data) } + private int enemySlotCountValue; + public DialogAntiAirDefense() { InitializeComponent(); + enemySlotCountValue = (int)EnemySlotCount.Value; } private void DialogAntiAirDefense_Load(object sender, EventArgs e) @@ -96,7 +99,7 @@ private void Updated() ShipData[] ships = GetShips().ToArray(); int formation = Formation.SelectedItem as FormationComboBoxData; int aaCutinKind = AACutinKind.SelectedItem as AACutinComboBoxData; - int enemyAircraftCount = (int)EnemySlotCount.Value; + int enemyAircraftCount = enemySlotCountValue; // 加重対空値 @@ -215,7 +218,7 @@ private void ResultView_CellFormatting(object sender, DataGridViewCellFormatting { int value = e.Value as int? ?? 0; - int enemySlot = (int)EnemySlotCount.Value; + int enemySlot = enemySlotCountValue; e.Value = string.Format("{0} ({1:p0})", value, (double)value / enemySlot); e.FormattingApplied = true; @@ -246,6 +249,7 @@ private void AACutinKind_SelectedIndexChanged(object sender, EventArgs e) private void EnemySlotCount_ValueChanged(object sender, EventArgs e) { + enemySlotCountValue = (int)EnemySlotCount.Value; Updated(); } From b92ed7a7188a679c2d0c84abd99b3f75399551e6 Mon Sep 17 00:00:00 2001 From: Andante Date: Tue, 2 Jan 2018 09:06:34 +0900 Subject: [PATCH 09/12] =?UTF-8?q?=E6=B3=A8=E9=87=88=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs b/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs index bcb2bf087..233e4404e 100644 --- a/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs +++ b/ElectronicObserver/Window/Dialog/DialogAntiAirDefense.cs @@ -55,8 +55,13 @@ public static implicit operator int(FormationComboBoxData data) } + /// + /// NumericUpDown から Value を正しく取得できないことがあるため、一旦これにキャッシュする + /// + /// https://github.com/andanteyk/ElectronicObserver/pull/197 private int enemySlotCountValue; + public DialogAntiAirDefense() { InitializeComponent(); From 7847bcef42e7af049dc3e2cdf86590f813b5425b Mon Sep 17 00:00:00 2001 From: Andante Date: Sun, 11 Feb 2018 19:49:18 +0900 Subject: [PATCH 10/12] =?UTF-8?q?=E6=96=B0=E3=81=97=E3=81=84=E8=A6=81?= =?UTF-8?q?=E7=B4=A0=E3=81=B8=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新対空カットイン(龍田, 伊勢型)への対応 * 一部の廃棄系任務に対応 * ship2 の仕様変更に対応 * 艦これ統計データベースへの送信機能を削除 * ログ:入渠時のログを追加 --- ElectronicObserver/Data/Constants.cs | 6 + .../Data/Quest/ProgressMultiDiscard.cs | 65 +++++++ .../Data/Quest/QuestProgressManager.cs | 28 +++ ElectronicObserver/ElectronicObserver.csproj | 2 +- ElectronicObserver/Observer/APIKancolleDB.cs | 170 ------------------ ElectronicObserver/Observer/APIObserver.cs | 11 +- .../Observer/kcsapi/api_get_member/ship2.cs | 23 ++- .../Observer/kcsapi/api_req_nyukyo/start.cs | 17 +- .../Other/Information/apilist.txt | 12 +- .../Other/Information/kcmemo.md | 149 +++++++++++++-- ElectronicObserver/Utility/Configuration.cs | 14 +- ElectronicObserver/Utility/Data/Calculator.cs | 54 ++++-- .../Dialog/DialogConfiguration.Designer.cs | 101 +---------- .../Window/Dialog/DialogConfiguration.cs | 8 - 14 files changed, 318 insertions(+), 342 deletions(-) create mode 100644 ElectronicObserver/Data/Quest/ProgressMultiDiscard.cs delete mode 100644 ElectronicObserver/Observer/APIKancolleDB.cs diff --git a/ElectronicObserver/Data/Constants.cs b/ElectronicObserver/Data/Constants.cs index da2177955..18d901875 100644 --- a/ElectronicObserver/Data/Constants.cs +++ b/ElectronicObserver/Data/Constants.cs @@ -873,6 +873,12 @@ public static string GetAACutinKind(int id) return "集中機銃(文月)"; case 23: return "機銃(非集中)(UIT-25)"; + case 24: + return "高角砲/機銃(非集中)(龍田)"; + case 25: + return "噴進砲改二/電探/三式弾(伊勢)"; + case 28: + return "噴進砲改二/電探(伊勢)"; default: return "不明"; } diff --git a/ElectronicObserver/Data/Quest/ProgressMultiDiscard.cs b/ElectronicObserver/Data/Quest/ProgressMultiDiscard.cs new file mode 100644 index 000000000..85bb2eef9 --- /dev/null +++ b/ElectronicObserver/Data/Quest/ProgressMultiDiscard.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace ElectronicObserver.Data.Quest +{ + [DataContract(Name = "ProgressMultiDiscard")] + public class ProgressMultiDiscard : ProgressData + { + + [DataMember] + private ProgressDiscard[] ProgressList; + + public ProgressMultiDiscard(QuestData quest, IEnumerable progressList) + : base(quest, 1) + { + ProgressList = progressList.ToArray(); + ProgressMax = progressList.Sum(p => p.ProgressMax); + } + + + public void Increment(IEnumerable equipments) + { + foreach (var p in ProgressList) + p.Increment(equipments); + + Progress = ProgressList.Sum(p => p.Progress); + } + + + public override void Increment() + { + throw new NotSupportedException(); + } + + public override void Decrement() + { + throw new NotSupportedException(); + } + + + public override void CheckProgress(QuestData q) + { + // do nothing + } + + + public override string ToString() + { + if (ProgressList.All(p => p.IsCleared)) + return "達成!"; + else + return string.Join(", ", ProgressList.Where(p => !p.IsCleared).Select(p => p.GetClearCondition() + ": " + p.ToString())); + } + + + public override string GetClearCondition() + { + return string.Join(", ", ProgressList.Select(p => p.GetClearCondition())); + } + } +} diff --git a/ElectronicObserver/Data/Quest/QuestProgressManager.cs b/ElectronicObserver/Data/Quest/QuestProgressManager.cs index 18c9881f3..8d2b5ecd5 100644 --- a/ElectronicObserver/Data/Quest/QuestProgressManager.cs +++ b/ElectronicObserver/Data/Quest/QuestProgressManager.cs @@ -25,6 +25,7 @@ namespace ElectronicObserver.Data.Quest [KnownType(typeof(ProgressDestruction))] [KnownType(typeof(ProgressDevelopment))] [KnownType(typeof(ProgressDiscard))] + [KnownType(typeof(ProgressMultiDiscard))] [KnownType(typeof(ProgressDocking))] [KnownType(typeof(ProgressExpedition))] [KnownType(typeof(ProgressImprovement))] @@ -367,6 +368,29 @@ void QuestUpdated(string apiname, dynamic data) Progresses.Add(new ProgressDiscard(q, 3, true, new int[] { 21 })); Progresses[q.QuestID].SharedCounterShift = 2; break; + case 676: //|676|週|装備開発力の集中整備|(中口径主砲x3, 副砲x3, 簡易輸送部材x1)廃棄, 鋼材2400保有|進捗は n/7 で1つごとに進む + Progresses.Add(new ProgressMultiDiscard(q, new[] { + new ProgressDiscard(q, 3, true, new[]{ 2 }), + new ProgressDiscard(q, 3, true, new[]{ 4 }), + new ProgressDiscard(q, 1, true, new[]{ 30 }), + })); + break; + case 663: //|663|季|新型艤装の継続研究|大口径主砲x10廃棄, 鋼材18000保有 + Progresses.Add(new ProgressDiscard(q, 10, true, new[] { 3 })); + break; + case 675: //|675|季|運用装備の統合整備|(艦上戦闘機x6, 機銃x4)廃棄, ボーキ800保有 + Progresses.Add(new ProgressMultiDiscard(q, new[] { + new ProgressDiscard(q, 6, true, new[]{ 6 }), + new ProgressDiscard(q, 4, true, new[]{ 21 }), + })); + break; + case 677: //|677|週|継戦支援能力の整備|(大口径主砲x4, 水上偵察機x2, 魚雷x3)廃棄, 鋼材3600保有 + Progresses.Add(new ProgressMultiDiscard(q, new[] { + new ProgressDiscard(q, 4, true, new[]{ 3 }), + new ProgressDiscard(q, 2, true, new[]{ 10 }), + new ProgressDiscard(q, 3, true, new[]{ 5 }), + })); + break; case 702: //|702|艦の「近代化改修」を実施せよ!|改修成功2 Progresses.Add(new ProgressModernization(q, 2)); @@ -546,6 +570,10 @@ public void EquipmentDiscarded(string apiname, Dictionary data) { p.Increment(ids); } + foreach (var p in Progresses.Values.OfType()) + { + p.Increment(ids); + } OnProgressChanged(); } diff --git a/ElectronicObserver/ElectronicObserver.csproj b/ElectronicObserver/ElectronicObserver.csproj index d17fb7cf2..fbfea9048 100644 --- a/ElectronicObserver/ElectronicObserver.csproj +++ b/ElectronicObserver/ElectronicObserver.csproj @@ -169,6 +169,7 @@ + @@ -193,7 +194,6 @@ - diff --git a/ElectronicObserver/Observer/APIKancolleDB.cs b/ElectronicObserver/Observer/APIKancolleDB.cs deleted file mode 100644 index ccac0376c..000000000 --- a/ElectronicObserver/Observer/APIKancolleDB.cs +++ /dev/null @@ -1,170 +0,0 @@ -using ElectronicObserver.Utility; -using Nekoxy; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Web; - -namespace ElectronicObserver.Observer -{ - - /// - /// 艦これ統計データベースへのデータ送信処理を行います。 - /// - /// http://kancolle-db.net/ - public class APIKancolleDB - { - - - private static readonly HashSet apis = new HashSet() { - "/kcsapi/api_port/port", - "/kcsapi/api_get_member/ship2", - "/kcsapi/api_get_member/ship3", - "/kcsapi/api_get_member/slot_item", - "/kcsapi/api_get_member/kdock", - "/kcsapi/api_get_member/mapinfo", - "/kcsapi/api_req_hensei/change", - "/kcsapi/api_req_kousyou/createship", - "/kcsapi/api_req_kousyou/getship", - "/kcsapi/api_req_kousyou/createitem", - "/kcsapi/api_req_map/start", - "/kcsapi/api_req_map/next", - "/kcsapi/api_req_map/select_eventmap_rank", - "/kcsapi/api_req_sortie/battle", - "/kcsapi/api_req_battle_midnight/battle", - "/kcsapi/api_req_battle_midnight/sp_midnight", - "/kcsapi/api_req_sortie/night_to_day", - "/kcsapi/api_req_sortie/battleresult", - "/kcsapi/api_req_combined_battle/battle", - "/kcsapi/api_req_combined_battle/airbattle", - "/kcsapi/api_req_combined_battle/midnight_battle", - "/kcsapi/api_req_combined_battle/battleresult", - "/kcsapi/api_req_sortie/airbattle", - "/kcsapi/api_req_combined_battle/battle_water", - "/kcsapi/api_req_combined_battle/sp_midnight", - }; - - - public APIKancolleDB() - { - - Utility.Configuration.Instance.ConfigurationChanged += ConfigurationChanged; - ConfigurationChanged(); - - // to avoid http 417 error - ServicePointManager.Expect100Continue = false; - - } - - private void ConfigurationChanged() - { - OAuth = Utility.Configuration.Config.Connection.SendKancolleOAuth; - - if (Utility.Configuration.Config.Connection.UseUpstreamProxy) - { - Proxy = new WebProxy("127.0.0.1", Utility.Configuration.Config.Connection.Port); - } - else - { - Proxy = null; - } - } - - private string OAuth; - private WebProxy Proxy; - - - /// - /// read the after-session, determinate whether it will send to kancolle-db.net - /// - public void ExecuteSession(Session session) - { - - if (string.IsNullOrEmpty(OAuth)) - { - return; - } - - // find the url in dict. - string url = session.Request.PathAndQuery; - - if (apis.Contains(url)) - { - PostToServer(session); - } - - } - - private static Regex RequestRegex = new Regex(@"&api(_|%5F)token=[0-9a-f]+|api(_|%5F)token=[0-9a-f]+&?", RegexOptions.Compiled); - - private void PostToServer(Session session) - { - - string oauth = OAuth; - string url = session.Request.PathAndQuery; - string request = session.Request.BodyAsString; - string response = session.Response.BodyAsString; - - request = RequestRegex.Replace(request, ""); - - try - { - - //* - using (System.Net.WebClient wc = new System.Net.WebClient()) - { - wc.Headers["User-Agent"] = "ElectronicObserver/v" + SoftwareInformation.VersionEnglish; - - if (Proxy != null) - { - wc.Proxy = Proxy; - } - - System.Collections.Specialized.NameValueCollection post = new System.Collections.Specialized.NameValueCollection - { - { "token", oauth }, - // agent key for 'ElectronicObserver' - // https://github.com/about518/kanColleDbPost/issues/3#issuecomment-105534030 - { "agent", "L57Mi4hJeCYinbbBSH5K" }, - { "url", url }, - { "requestbody", request }, - { "responsebody", response } - }; - - wc.UploadValuesCompleted += (sender, e) => - { - if (e.Error != null) - { - - // 結構頻繁に出るのでレポートは残さない方針で 申し訳ないです - //Utility.ErrorReporter.SendErrorReport( e.Error, string.Format( "艦これ統計データベースへの {0} の送信に失敗しました。", url.Substring( url.IndexOf( "/api" ) + 1 ) ) ); - - Utility.Logger.Add(1, string.Format("艦これ統計データベースへの {0} の送信に失敗しました。{1}", url.Substring(url.IndexOf("/api") + 1), e.Error.Message)); - - } - else - { - Utility.Logger.Add(0, string.Format("艦これ統計データベースへ {0} を送信しました。", url.Substring(url.IndexOf("/api") + 1))); - } - }; - - wc.UploadValuesAsync(new Uri("http://api.kancolle-db.net/2/"), post); - } - //*/ - - } - catch (Exception ex) - { - - Utility.ErrorReporter.SendErrorReport(ex, "艦これ統計データベースへの送信中にエラーが発生しました。"); - } - - } - - } -} diff --git a/ElectronicObserver/Observer/APIObserver.cs b/ElectronicObserver/Observer/APIObserver.cs index f74429f3c..b985c05ad 100644 --- a/ElectronicObserver/Observer/APIObserver.cs +++ b/ElectronicObserver/Observer/APIObserver.cs @@ -40,7 +40,7 @@ public sealed class APIObserver public event ProxyStartedEventHandler ProxyStarted = delegate { }; private Control UIControl; - private APIKancolleDB DBSender; + public event APIReceivedEventHandler RequestReceived = delegate { }; public event APIReceivedEventHandler ResponseReceived = delegate { }; @@ -137,8 +137,7 @@ private APIObserver() ServerAddress = null; - DBSender = new APIKancolleDB(); - + HttpProxy.AfterSessionComplete += HttpProxy_AfterSessionComplete; } @@ -359,12 +358,6 @@ void HttpProxy_AfterSessionComplete(Session session) string body = session.Response.BodyAsString; UIControl.BeginInvoke((Action)(() => { LoadResponse(url, body); })); - // kancolle-db.netに送信する - if (Utility.Configuration.Config.Connection.SendDataToKancolleDB) - { - Task.Run((Action)(() => DBSender.ExecuteSession(session))); - } - } diff --git a/ElectronicObserver/Observer/kcsapi/api_get_member/ship2.cs b/ElectronicObserver/Observer/kcsapi/api_get_member/ship2.cs index 52c00befd..978e1d883 100644 --- a/ElectronicObserver/Observer/kcsapi/api_get_member/ship2.cs +++ b/ElectronicObserver/Observer/kcsapi/api_get_member/ship2.cs @@ -19,14 +19,25 @@ public override void OnResponseReceived(dynamic data) //api_data - db.Ships.Clear(); - foreach (var elem in data.api_data) - { - var a = new ShipData(); - a.LoadFromResponse(APIName, elem); - db.Ships.Add(a); + var ships = (dynamic[])data.api_data; + + if (ships.Length > 1) + db.Ships.Clear(); + foreach (var elem in ships) + { + int id = (int)elem.api_id; + var ship = db.Ships[id]; + + if (ship != null) + ship.LoadFromResponse(APIName, elem); + else + { + var a = new ShipData(); + a.LoadFromResponse(APIName, elem); + db.Ships.Add(a); + } } diff --git a/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs b/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs index 233b7b89d..aae9e4b0b 100644 --- a/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs +++ b/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs @@ -13,45 +13,46 @@ namespace ElectronicObserver.Observer.kcsapi.api_req_nyukyo public class start : APIBase { - public override void OnRequestReceived(Dictionary data) { KCDatabase db = KCDatabase.Instance; DockData dock = db.Docks[int.Parse(data["api_ndock_id"])]; + bool bucketUsed = data["api_highspeed"] == "1"; int shipID = int.Parse(data["api_ship_id"]); ShipData ship = db.Ships[shipID]; + Utility.Logger.Add(2, string.Format("入渠ドック #{0}で {1} の修復を開始しました。(燃料x{2}, 鋼材x{3}, {4})", + dock.DockID, ship.NameWithLevel, + ship.RepairFuel, ship.RepairSteel, + bucketUsed ? "高速修復材x1" : ("修理完了予定: " + DateTimeHelper.TimeToCSVString(DateTime.Now + TimeSpan.FromMilliseconds(ship.RepairTime))) + )); + + db.Material.Fuel -= ship.RepairFuel; db.Material.Steel -= ship.RepairSteel; - if (data["api_highspeed"] == "1") + if (bucketUsed) { - ship.Repair(); db.Material.InstantRepair--; - } else if (ship.RepairTime <= 60000) { - ship.Repair(); - } else { - //この場合は直後に ndock が呼ばれるので自力で更新しなくてもよい /* dock.State = 1; dock.ShipID = shipID; dock.CompletionTime = DateTime.Now.AddMilliseconds( ship.RepairTime ); */ - } diff --git a/ElectronicObserver/Other/Information/apilist.txt b/ElectronicObserver/Other/Information/apilist.txt index 7a80520c4..8b936ff01 100644 --- a/ElectronicObserver/Other/Information/apilist.txt +++ b/ElectronicObserver/Other/Information/apilist.txt @@ -2096,9 +2096,15 @@ api_req_sortie/goback_port :単艦退避受諾 (情報なし) :退避したときのみ呼ばれる; 退避艦等の情報は battleresult に含まれている -api_get_member/ship2 :旧進撃中(現在はケッコンカッコカリ・給糧艦使用(未確認)のみだと思われる) - api_data :portに同じ - api_data_deck :deckに同じ +Request.api_get_member/ship2 :艦船情報 + spi_sort_order + api_shipid :更新対象の艦船ID 配列にはならなさそう、存在しない場合もあり得る + api_sort_key + +api_get_member/ship2 :艦船情報(現在はケッコンカッコカリ・給糧艦使用時等、限られたシーンでのみ使用) + (以下のメンバは api_result 等と同じ階層に存在するため注意) + api_data :艦船データ req.api_shipid が存在する場合は指定された艦1隻のみ、存在しなければ全艦? + api_data_deck :艦隊データ 指定にかかわらず全艦隊のデータが送られてくる Request.api_get_member/ship_deck :進撃中 api_deck_rid :出撃艦隊ID 複数艦隊の時はつなげる? (ex. 連合艦隊時は 12) diff --git a/ElectronicObserver/Other/Information/kcmemo.md b/ElectronicObserver/Other/Information/kcmemo.md index 41b3477c9..53477e9cc 100644 --- a/ElectronicObserver/Other/Information/kcmemo.md +++ b/ElectronicObserver/Other/Information/kcmemo.md @@ -68,9 +68,17 @@ value = min + ceil( ( max - min ) * ( 0.4 or 0.8 ) * Lv / 99 ) |ID|艦名| |--:|:--| -|740|???| -|741|???| -|742|???| +|732|節分如月| +|733|節分佐渡| +|734|節分朝霜| +|735|正月大和| +|736|正月対馬| +|737|正月Richelieu| +|738|正月Warspite| +|739|打ち上げ秋雲| +|740|売り子風雲| +|741|超修羅場秋雲| +|742|大掃除対馬| |743|Xmas伊8| |744|Xmas霰| |745|Xmas衣笠| @@ -84,7 +92,7 @@ value = min + ceil( ( max - min ) * ( 0.4 or 0.8 ) * Lv / 99 ) |753|修羅場秋雲| |754|???| |755|???| -|756|???| +|756|秋不知火| |757|スリガオ海峡突入満潮改二| |758|スリガオ海峡突入時雨改二| |759|スリガオ海峡突入最上| @@ -92,7 +100,7 @@ value = min + ceil( ( max - min ) * ( 0.4 or 0.8 ) * Lv / 99 ) |761|スリガオ海峡突入朝雲| |762|晩秋狭霧| |763|ハロウィン瑞穂| -|764|???| +|764|秋蒼龍| |765|秋川内| |766|秋秋雲| |767|秋藤波| @@ -771,7 +779,7 @@ phase/combat に API ごとの戦闘の流れが書いてある | 9|高角砲/高射装置|| |10|高角砲/集中機銃/電探|摩耶改二| |11|高角砲/集中機銃|摩耶改二| -|12|集中機銃/機銃/電探|| +|12|集中機銃/機銃(対空≧3)/電探|| |13|???|| |14|高角砲/機銃/電探|五十鈴改二| |15|高角砲/機銃|五十鈴改二| @@ -783,6 +791,9 @@ phase/combat に API ごとの戦闘の流れが書いてある |21|高角砲/電探|由良改二| |22|集中機銃|文月改二| |23|機銃(非集中)|UIT-25以降| +|24|高角砲/機銃(非集中)|龍田改二| +|25|噴進砲改二/電探/三式弾|伊勢型改| +|28|噴進砲改二/電探|伊勢型改, 武蔵改| 秋月型のみ対空電探でなくても可。 @@ -791,6 +802,7 @@ phase/combat に API ごとの戦闘の流れが書いてある * 対空電探 : 対空 >= 2 の電探 * 高角砲+高射装置 : 対空 >= 8 の高角砲 * 集中機銃 : 対空 >= 9 の機銃 +* 機銃(非集中) : 3 <= 対空 <= 8 の機銃 #### 敵ボイス @@ -1116,9 +1128,11 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |464|霞改二|上陸用舟艇, 司令部施設, 特型内火艇|| |466, 467|翔鶴改二甲, 瑞鶴改二甲|輸送機材, 噴式戦闘機, 噴式戦闘爆撃機, 噴式攻撃機, 噴式偵察機|| |470|霞改二乙|大型電探, 上陸用舟艇, 特型内火艇|| +|478|龍田改二|上陸用舟艇, オートジャイロ, 特型内火艇|副砲, 水上偵察機, 大型電探| |488|由良改二|水上爆撃機, 特殊潜航艇, 上陸用舟艇, 航空要員, 水上戦闘機, 特型内火艇|| |491|Commandant Teste|中口径主砲, ソナー, オートジャイロ, 航空要員, 大型探照灯|爆雷, 特殊潜航艇, 上陸用舟艇, 特型内火艇| |496|Zara due|水上爆撃機, 航空要員, 大型探照灯, 水上戦闘機|| +|498|村雨改二|上陸用舟艇, 司令部施設|| |500|神威改母|中口径主砲, 副砲, ソナー, 爆雷, 上陸用舟艇, 追加装甲(中型), 探照灯, 照明弾, 司令部施設, 対地装備, 水上艦要員, 大型ソナー, 大型飛行艇, 特型内火艇, 輸送機材|| |521|春日丸||艦上攻撃機, 艦上偵察機, 大型電探, オートジャイロ, 対潜哨戒機, 司令部施設, 大型ソナー| |526|大鷹||艦上偵察機, オートジャイロ, 対潜哨戒機, 大型ソナー| @@ -1241,6 +1255,7 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |304|日|「演習」で他提督を圧倒せよ!|演習勝利5 |302|週|大規模演習|演習勝利20 |311|月|精鋭艦隊演習|演習勝利7|デイリー扱い +|318|月|給糧艦「伊良湖」の支援|演習勝利3, 秘書艦に戦闘糧食x2装備|要軽巡2以上, 戦闘糧食を装備するまで進捗表示0| |402|日|「遠征」を3回成功させよう!|遠征成功3 |403|日|「遠征」を10回成功させよう!|遠征成功10 |404|週|大規模遠征作戦、発令!|遠征成功30 @@ -1258,17 +1273,19 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |609|日|軍縮条約対応!|解体2 |619|日|装備の改修強化|装備改修1(失敗可) |673|日|装備開発力の整備|小口径主砲廃棄4個|進捗は1/5から始まる(3個廃棄時点で80%達成になる) -|674|日|工廠環境の整備|機銃廃棄3個,鋼材300保有|進捗は2/5から始まる(1個廃棄時点で50%,2個〃で80%達成になる) +|674|日|工廠環境の整備|機銃廃棄3個, 鋼材300保有|進捗は2/5から始まる(1個廃棄時点で50%,2個〃で80%達成になる) |613|週|資源の再利用|廃棄24回 |638|週|対空機銃量産|機銃廃棄6個 -|676|週|装備開発力の集中整備|(中口径主砲x3,副砲x3,簡易輸送部材x1)廃棄,鋼材2400保有|進捗は n/7 で1つごとに進む -|626|月|精鋭「艦戦」隊の新編成|熟練搭乗員,零式艦戦21型>>装備の鳳翔旗艦,(零式艦戦21型x2,九六式艦戦x1)廃棄 -|628|月|機種転換|零式艦戦21型(熟練)>>装備の空母旗艦,零式艦戦52型x2廃棄 -|645|月|「洋上補給」物資の調達|三式弾廃棄,(燃料750,弾薬750,ドラム缶(輸送用)x2,九一式徹甲弾)保有 -|637|季|「熟練搭乗員」養成|九六式艦戦>>★10装備の鳳翔旗艦,勲章2 -|643|季|主力「陸攻」の調達|零式艦戦21型x2廃棄,(九六式陸攻x1,九七式艦攻x2)保有 -|663|季|新型艤装の継続研究|大口径主砲x10廃棄,鋼材18000保有 -|675|季|運用装備の統合整備|(艦上戦闘機x6,機銃x4)廃棄,ボーキ800保有 +|676|週|装備開発力の集中整備|(中口径主砲x3, 副砲x3, 簡易輸送部材x1)廃棄, 鋼材2400保有|進捗は n/7 で1つごとに進む +|626|月|精鋭「艦戦」隊の新編成|熟練搭乗員, 零式艦戦21型>>装備の鳳翔旗艦, (零式艦戦21型x2,九六式艦戦x1)廃棄 +|628|月|機種転換|零式艦戦21型(熟練)>>装備の空母旗艦, 零式艦戦52型x2廃棄 +|645|月|「洋上補給」物資の調達|三式弾廃棄, (燃料750, 弾薬750, ドラム缶(輸送用)x2, 九一式徹甲弾)保有 +|637|季|「熟練搭乗員」養成|九六式艦戦>>★10装備の鳳翔旗艦, 勲章2 +|643|季|主力「陸攻」の調達|零式艦戦21型x2廃棄, (九六式陸攻x1, 九七式艦攻x2)保有 +|663|季|新型艤装の継続研究|大口径主砲x10廃棄, 鋼材18000保有 +|675|季|運用装備の統合整備|(艦上戦闘機x6, 機銃x4)廃棄, ボーキ800保有 +|677|週|継戦支援能力の整備|(大口径主砲x4, 水上偵察機x2, 魚雷x3)廃棄, 鋼材3600保有 +|678|季|主力艦上戦闘機の更新|(九六式艦戦x3, 零式艦戦21型x5)廃棄, 秘書艦の第1・第2スロットに零式艦戦52型装備, ボーキ4000保有 |702|日|艦の「近代化改修」を実施せよ!|近代化改修成功2 |703|週|「近代化改修」を進め、戦備を整えよ!|近代化改修成功15 @@ -1347,6 +1364,7 @@ Bismarck dreiに対する魚雷装備・試製51cm連装砲といったものの |576|深海12inch三連装砲|231|30.5cm三連装砲| |577|深海15inch四連装砲|245|38cm四連装砲| |578|深海15inch連装砲後期型|190|38.1cm Mk.I連装砲| +|580|深海待伏魚雷|58|61cm五連装(酸素)魚雷| > 567(沿岸設置レーダー)については、31(32号対水上電探)だったはずが typo したものと考えられる。 @@ -1705,9 +1723,12 @@ Lv. 3 の離島棲鬼には装甲破壊効果はないのではないかと思 ##### 開発資材 -基本的には、改装に必要な鋼材の量に依存する。 +改装に必要な鋼材の量に依存する。 +が、基本的には決め打ちされている。 ``` +if ( 龍田改 からの改装である ) + return 15; if ( ( Saratoga Mk.II | Saratoga Mk.II Mod.2 ) からの改装である ) return 20; else if ( 改装設計図が必要 && ( 鈴谷改二 | 鈴谷航改二 | 熊野改二 | 熊野航改二 ) からの改装ではない ) @@ -1723,6 +1744,8 @@ else return 20; ソースコード中に決め打ちされている。 ``` +if ( 龍田改 からの改装である ) + return 5; if ( ( 鈴谷改二 | 鈴谷航改二 | 熊野改二 | 熊野航改二 ) からの改装である ) return 20; else if ( ( Saratoga Mk.II | Saratoga Mk.II Mod.2 ) からの改装である ) @@ -2096,5 +2119,99 @@ if( 対潜改修値 >= 9 ) { 艦型指定のものは、未改造の艦にも適用される。 +#### 改修済みの初期装備 + +* 478 龍田改二 : 53cm連装魚雷 +3 +* 498 村雨改二 : 25mm三連装機銃 +3 + + +#### 対空噴進弾幕について + +対空噴進弾幕のクライアント側における表示処理についてまとめる。 + + +##### 対空砲火ID +`battle.consts.AntiAircraftEffectType` + +``` +なし = -1 +通常 = 0 +高角砲 = 1 +噴進砲 = 2 +噴進砲改二 = 3 +三式弾 = 4 +三式弾 + 噴進砲改二 = 5 +``` + + +##### 対空戦処理 +`battle.phase.day.PhaseKouku` + +``` +対空艦数 = 0; + +((存在しない or 退避中)の艦を除く全味方艦に対して) { + + 対空砲火ID = 対空砲火ID取得(対象艦); // 後述 + + if (対空砲火ID != -1) { + + 対空艦数++; + + if(対象艦.航空戦での被ダメージ <= 0 && 対空砲火ID == (3, 5)) // 噴進砲改二カットインの時 + 対空噴進弾幕表示(); + else if(対空砲火ID == (4, 5)) // 三式弾カットインの時 + 三式弾炸裂表示(); + + 対空砲火表示(); + } +} + +if (対空艦数 == 0) + 旗艦.対空砲火表示(); + +``` + + +`battle.util.SlotitemUtil.hasAntiAircraftAbility` + +``` +int 対空砲火ID取得(対象艦) { + if (対象艦 == null) return -1; + if (対象艦.現在HP <= 0) return -1; + if (対象艦.退避中) return -1; + + + 艦種フラグ = 対象艦.艦種 == (6, 7, 10, 11, 16, 18); // 航巡, 軽母, 航戦, 空母, 水母, 装母 + 装備 = 対象艦.拡張スロットも含む装備リスト; + + if (装備.Contains(eq => eq.Category == 18)) { // 対空強化弾(≒三式弾) + if (艦種フラグ && 装備.Contains(eq => eq.ID == 274)) // 12cm30連装噴進砲改二 + return 5; + else + return 4; + } + if (艦種フラグ && 装備.Contains(eq => eq.ID == 274)) // 12cm30連装噴進砲改二 + return 3; + if (装備.Contains(eq => eq.ID == 51)) // 12cm30連装噴進砲 + return 2; + if (装備.Contains(eq => eq.Icon == 16)) // 高角砲 + return 1; + if (装備.Contains(eq => eq.Category == 21)) // 対空機銃 + return 0; + + if (装備.Contains(eq => eq.Icon == 11)) { // 電探 + if (装備.Contains(eq => eq.Category == 11 && eq.AntiAir > 0) // 対空 > 0 の水上爆撃機 ...? + return 0; + } + + return -1; +} +``` + +要するに、対空噴進弾幕表示は「装備・艦種条件を満たしたうえで、航空戦での被ダメージが 0 のとき」に必ず表示される…はずである。 +当該艦がターゲットされていなくても表示される。 + + diff --git a/ElectronicObserver/Utility/Configuration.cs b/ElectronicObserver/Utility/Configuration.cs index c56b541b4..5c7f6334a 100644 --- a/ElectronicObserver/Utility/Configuration.cs +++ b/ElectronicObserver/Utility/Configuration.cs @@ -124,17 +124,7 @@ public class ConfigConnection : ConfigPartBase public string DownstreamProxy { get; set; } - /// - /// kancolle-db.netに送信する - /// - public bool SendDataToKancolleDB { get; set; } - - /// - /// kancolle-db.netのOAuth認証 - /// - public string SendKancolleOAuth { get; set; } - - + public ConfigConnection() { @@ -152,8 +142,6 @@ public ConfigConnection() UpstreamProxyAddress = "127.0.0.1"; UseSystemProxy = false; DownstreamProxy = ""; - SendDataToKancolleDB = false; - SendKancolleOAuth = ""; } } diff --git a/ElectronicObserver/Utility/Data/Calculator.cs b/ElectronicObserver/Utility/Data/Calculator.cs index 0e68fa63d..46c6b9e61 100644 --- a/ElectronicObserver/Utility/Data/Calculator.cs +++ b/ElectronicObserver/Utility/Data/Calculator.cs @@ -61,8 +61,8 @@ public static int GetParameterFromLevel(int min, int max, int lv) { EquipmentTypes.CarrierBasedFighter, 0.2 }, { EquipmentTypes.CarrierBasedBomber, 0.25 }, { EquipmentTypes.SeaplaneFighter, 0.2 }, - { EquipmentTypes.Interceptor, 0.2 }, - }; + { EquipmentTypes.Interceptor, 0.2 }, + }; @@ -1165,8 +1165,10 @@ public static int GetAACutinKind(int shipID, int[] slot) int aaradar = 0; int maingunl = 0; int aashell = 0; - int aagun = 0; + int aagun_total = 0; + int aagun_medium = 0; int aagun_concentrated = 0; + int aarocketmod = 0; var slotmaster = slot.Select(id => KCDatabase.Instance.MasterEquipments[id]).Where(eq => eq != null).ToArray(); @@ -1201,10 +1203,15 @@ public static int GetAACutinKind(int shipID, int[] slot) } else if (eq.CategoryType == EquipmentTypes.AAGun) { - aagun++; + aagun_total++; + + if (eq.EquipmentID == 274) // 噴進砲改二 + aarocketmod++; if (eq.IsConcentratedAAGun) aagun_concentrated++; + else if (eq.AA >= 3) + aagun_medium++; } } @@ -1222,7 +1229,7 @@ public static int GetAACutinKind(int shipID, int[] slot) case 423: // 初月 case 357: // 初月改 case 532: // 涼月 - case 537: // 涼月改 + case 537: // 涼月改 if (highangle >= 2 && radar >= 1) { return 1; @@ -1248,7 +1255,7 @@ public static int GetAACutinKind(int shipID, int[] slot) break; case 141: // 五十鈴改二 - if (highangle >= 1 && aagun >= 1) + if (highangle >= 1 && aagun_total >= 1) { if (aaradar >= 1) return 14; @@ -1258,7 +1265,7 @@ public static int GetAACutinKind(int shipID, int[] slot) break; case 470: // 霞改二乙 - if (highangle >= 1 && aagun >= 1) + if (highangle >= 1 && aagun_total >= 1) { if (aaradar >= 1) return 16; @@ -1293,9 +1300,30 @@ public static int GetAACutinKind(int shipID, int[] slot) case 539: // UIT-25 case 530: // 伊504 - if (aagun - aagun_concentrated >= 1) + if (aagun_medium >= 1) return 23; break; + + case 478: // 龍田改二 + if (highangle >= 1 && aagun_medium >= 1) + return 24; + break; + + case 82: // 伊勢改 + case 88: // 日向改 + if (aarocketmod >= 1 && aaradar >= 1) + { + if (aashell >= 1) + return 25; + + return 28; + } + break; + + case 148: // 武蔵改 + if (aarocketmod >= 1 && aaradar >= 1) + return 28; + break; } @@ -1325,8 +1353,8 @@ public static int GetAACutinKind(int shipID, int[] slot) return 9; } - if (aagun_concentrated >= 1 && aagun >= 2 && aaradar >= 1) - { //注: 機銃2なのは集中機銃がダブるため + if (aagun_concentrated >= 1 && (aagun_concentrated + aagun_medium) >= 2 && aaradar >= 1) + { return 12; } @@ -1546,6 +1574,9 @@ public static int GetFixedAirDefense(double adjustedAAValue, double adjustedFlee { 21, 5 }, { 22, 2 }, { 23, 1 }, + { 24, 3 }, + { 25, 7 }, + { 28, 4 }, }); @@ -1576,6 +1607,9 @@ public static int GetFixedAirDefense(double adjustedAAValue, double adjustedFlee { 21, 1.45 }, { 22, 1.2 }, { 23, 1.05 }, + { 24, 1.25 }, + { 25, 1.55 }, + { 28, 1.4 }, }); diff --git a/ElectronicObserver/Window/Dialog/DialogConfiguration.Designer.cs b/ElectronicObserver/Window/Dialog/DialogConfiguration.Designer.cs index cb3ba74ef..c2b019f1a 100644 --- a/ElectronicObserver/Window/Dialog/DialogConfiguration.Designer.cs +++ b/ElectronicObserver/Window/Dialog/DialogConfiguration.Designer.cs @@ -231,13 +231,6 @@ private void InitializeComponent() this.Notification_Repair = new System.Windows.Forms.Button(); this.Notification_Construction = new System.Windows.Forms.Button(); this.Notification_Expedition = new System.Windows.Forms.Button(); - this.tabPage15 = new System.Windows.Forms.TabPage(); - this.groupBox5 = new System.Windows.Forms.GroupBox(); - this.label22 = new System.Windows.Forms.Label(); - this.Database_SendKancolleOAuth = new System.Windows.Forms.TextBox(); - this.Database_LinkKCDB = new System.Windows.Forms.LinkLabel(); - this.labelKdb = new System.Windows.Forms.Label(); - this.Database_SendDataToKancolleDB = new System.Windows.Forms.CheckBox(); this.tabPage17 = new System.Windows.Forms.TabPage(); this.BGMPlayer_SyncBrowserMute = new System.Windows.Forms.CheckBox(); this.BGMPlayer_SetVolumeAll = new System.Windows.Forms.Button(); @@ -298,8 +291,6 @@ private void InitializeComponent() this.SubWindow_Json.SuspendLayout(); this.SubWindow_Json_SealingPanel.SuspendLayout(); this.tabPage11.SuspendLayout(); - this.tabPage15.SuspendLayout(); - this.groupBox5.SuspendLayout(); this.tabPage17.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.BGMPlayer_VolumeAll)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.BGMPlayer_ControlGrid)).BeginInit(); @@ -318,7 +309,6 @@ private void InitializeComponent() this.tabControl1.Controls.Add(this.tabPage6); this.tabControl1.Controls.Add(this.tabPage7); this.tabControl1.Controls.Add(this.tabPage11); - this.tabControl1.Controls.Add(this.tabPage15); this.tabControl1.Controls.Add(this.tabPage17); this.tabControl1.Location = new System.Drawing.Point(0, 0); this.tabControl1.Multiline = true; @@ -1025,7 +1015,7 @@ private void InitializeComponent() this.Debug_SealingPanel.Controls.Add(this.Debug_APIListPathSearch); this.Debug_SealingPanel.Location = new System.Drawing.Point(0, 56); this.Debug_SealingPanel.Name = "Debug_SealingPanel"; - this.Debug_SealingPanel.Size = new System.Drawing.Size(696, 275); + this.Debug_SealingPanel.Size = new System.Drawing.Size(696, 273); this.Debug_SealingPanel.TabIndex = 1; // // Debug_APIListPath @@ -2688,7 +2678,7 @@ private void InitializeComponent() // this.label10.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(3, 346); + this.label10.Location = new System.Drawing.Point(3, 344); this.label10.Name = "label10"; this.label10.Size = new System.Drawing.Size(238, 15); this.label10.TabIndex = 5; @@ -2744,81 +2734,6 @@ private void InitializeComponent() this.Notification_Expedition.UseVisualStyleBackColor = true; this.Notification_Expedition.Click += new System.EventHandler(this.Notification_Expedition_Click); // - // tabPage15 - // - this.tabPage15.Controls.Add(this.groupBox5); - this.tabPage15.Location = new System.Drawing.Point(4, 24); - this.tabPage15.Name = "tabPage15"; - this.tabPage15.Padding = new System.Windows.Forms.Padding(3); - this.tabPage15.Size = new System.Drawing.Size(696, 372); - this.tabPage15.TabIndex = 8; - this.tabPage15.Text = "データベース"; - this.tabPage15.UseVisualStyleBackColor = true; - // - // groupBox5 - // - this.groupBox5.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupBox5.Controls.Add(this.label22); - this.groupBox5.Controls.Add(this.Database_SendKancolleOAuth); - this.groupBox5.Controls.Add(this.Database_LinkKCDB); - this.groupBox5.Controls.Add(this.labelKdb); - this.groupBox5.Controls.Add(this.Database_SendDataToKancolleDB); - this.groupBox5.Location = new System.Drawing.Point(6, 6); - this.groupBox5.Name = "groupBox5"; - this.groupBox5.Size = new System.Drawing.Size(684, 117); - this.groupBox5.TabIndex = 5; - this.groupBox5.TabStop = false; - this.groupBox5.Text = "艦これ統計データベース"; - // - // label22 - // - this.label22.AutoSize = true; - this.label22.Location = new System.Drawing.Point(6, 19); - this.label22.Name = "label22"; - this.label22.Size = new System.Drawing.Size(414, 30); - this.label22.TabIndex = 0; - this.label22.Text = "「艦これ統計データベース」へデータを送信できます。\r\n詳細やアクセスキーの取得は以下のサイトを参照してください。(外部ブラウザが開きます)"; - // - // Database_SendKancolleOAuth - // - this.Database_SendKancolleOAuth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.Database_SendKancolleOAuth.Location = new System.Drawing.Point(87, 86); - this.Database_SendKancolleOAuth.Name = "Database_SendKancolleOAuth"; - this.Database_SendKancolleOAuth.Size = new System.Drawing.Size(591, 23); - this.Database_SendKancolleOAuth.TabIndex = 4; - // - // Database_LinkKCDB - // - this.Database_LinkKCDB.AutoSize = true; - this.Database_LinkKCDB.Location = new System.Drawing.Point(6, 49); - this.Database_LinkKCDB.Name = "Database_LinkKCDB"; - this.Database_LinkKCDB.Size = new System.Drawing.Size(141, 15); - this.Database_LinkKCDB.TabIndex = 1; - this.Database_LinkKCDB.TabStop = true; - this.Database_LinkKCDB.Text = "http://kancolle-db.net/"; - this.Database_LinkKCDB.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.Database_LinkKCDB_LinkClicked); - // - // labelKdb - // - this.labelKdb.AutoSize = true; - this.labelKdb.Location = new System.Drawing.Point(6, 89); - this.labelKdb.Name = "labelKdb"; - this.labelKdb.Size = new System.Drawing.Size(75, 15); - this.labelKdb.TabIndex = 3; - this.labelKdb.Text = "アクセスキー:"; - // - // Database_SendDataToKancolleDB - // - this.Database_SendDataToKancolleDB.AutoSize = true; - this.Database_SendDataToKancolleDB.Location = new System.Drawing.Point(9, 67); - this.Database_SendDataToKancolleDB.Name = "Database_SendDataToKancolleDB"; - this.Database_SendDataToKancolleDB.Size = new System.Drawing.Size(190, 19); - this.Database_SendDataToKancolleDB.TabIndex = 2; - this.Database_SendDataToKancolleDB.Text = "艦これ統計データベースに送信する"; - this.Database_SendDataToKancolleDB.UseVisualStyleBackColor = true; - // // tabPage17 // this.tabPage17.Controls.Add(this.BGMPlayer_SyncBrowserMute); @@ -2908,7 +2823,7 @@ private void InitializeComponent() this.BGMPlayer_ControlGrid.RowHeadersVisible = false; this.BGMPlayer_ControlGrid.RowTemplate.Height = 21; this.BGMPlayer_ControlGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; - this.BGMPlayer_ControlGrid.Size = new System.Drawing.Size(684, 295); + this.BGMPlayer_ControlGrid.Size = new System.Drawing.Size(684, 293); this.BGMPlayer_ControlGrid.TabIndex = 0; this.BGMPlayer_ControlGrid.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.BGMPlayer_ControlGrid_CellContentClick); this.BGMPlayer_ControlGrid.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.BGMPlayer_ControlGrid_CellFormatting); @@ -3093,9 +3008,6 @@ private void InitializeComponent() this.SubWindow_Json_SealingPanel.PerformLayout(); this.tabPage11.ResumeLayout(false); this.tabPage11.PerformLayout(); - this.tabPage15.ResumeLayout(false); - this.groupBox5.ResumeLayout(false); - this.groupBox5.PerformLayout(); this.tabPage17.ResumeLayout(false); this.tabPage17.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.BGMPlayer_VolumeAll)).EndInit(); @@ -3223,12 +3135,6 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox FormBrowser_FlashWMode; private System.Windows.Forms.Label label20; private System.Windows.Forms.ComboBox FormBrowser_FlashQuality; - private System.Windows.Forms.TabPage tabPage15; - private System.Windows.Forms.LinkLabel Database_LinkKCDB; - private System.Windows.Forms.Label label22; - private System.Windows.Forms.TextBox Database_SendKancolleOAuth; - private System.Windows.Forms.Label labelKdb; - private System.Windows.Forms.CheckBox Database_SendDataToKancolleDB; private System.Windows.Forms.TabPage tabPage16; private System.Windows.Forms.CheckBox FormHeadquarters_BlinkAtMaximum; private System.Windows.Forms.ComboBox FormFleet_AirSuperiorityMethod; @@ -3264,7 +3170,6 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox FormArsenal_BlinkAtCompletion; private System.Windows.Forms.TabPage tabPage19; private System.Windows.Forms.CheckBox FormDock_BlinkAtCompletion; - private System.Windows.Forms.GroupBox groupBox5; private System.Windows.Forms.CheckedListBox FormHeadquarters_Visibility; private System.Windows.Forms.Label label26; private System.Windows.Forms.Button Notification_AnchorageRepair; diff --git a/ElectronicObserver/Window/Dialog/DialogConfiguration.cs b/ElectronicObserver/Window/Dialog/DialogConfiguration.cs index 3bea04efb..76bb0c15c 100644 --- a/ElectronicObserver/Window/Dialog/DialogConfiguration.cs +++ b/ElectronicObserver/Window/Dialog/DialogConfiguration.cs @@ -527,10 +527,6 @@ public void FromConfiguration(Configuration.ConfigurationData config) setSilencioConfig(issilenced); } - //[データベース] - Database_SendDataToKancolleDB.Checked = config.Connection.SendDataToKancolleDB; - Database_SendKancolleOAuth.Text = config.Connection.SendKancolleOAuth; - //[BGM] BGMPlayer_Enabled.Checked = config.BGMPlayer.Enabled; BGMHandles = config.BGMPlayer.Handles.ToDictionary(h => h.HandleID); @@ -752,10 +748,6 @@ public void ToConfiguration(Configuration.ConfigurationData config) //[通知] setSilencioConfig(Notification_Silencio.Checked); - //[データベース] - config.Connection.SendDataToKancolleDB = Database_SendDataToKancolleDB.Checked; - config.Connection.SendKancolleOAuth = Database_SendKancolleOAuth.Text; - //[BGM] config.BGMPlayer.Enabled = BGMPlayer_Enabled.Checked; for (int i = 0; i < BGMPlayer_ControlGrid.Rows.Count; i++) From 3f03e55cd57650f211891f4526e57ec3078df97e Mon Sep 17 00:00:00 2001 From: Andante Date: Sun, 11 Feb 2018 22:35:45 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=E3=83=AD=E3=82=B0=EF=BC=9A=E5=85=A5?= =?UTF-8?q?=E6=B8=A0=E3=83=AD=E3=82=B0=E3=81=AB=E5=BD=93=E6=99=82=E3=81=AE?= =?UTF-8?q?HP=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs b/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs index aae9e4b0b..4cbc4f317 100644 --- a/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs +++ b/ElectronicObserver/Observer/kcsapi/api_req_nyukyo/start.cs @@ -25,8 +25,9 @@ public override void OnRequestReceived(Dictionary data) ShipData ship = db.Ships[shipID]; - Utility.Logger.Add(2, string.Format("入渠ドック #{0}で {1} の修復を開始しました。(燃料x{2}, 鋼材x{3}, {4})", + Utility.Logger.Add(2, string.Format("入渠ドック #{0}で {1} ({2}/{3}) の修復を開始しました。(燃料x{4}, 鋼材x{5}, {6})", dock.DockID, ship.NameWithLevel, + ship.HPCurrent, ship.HPMax, ship.RepairFuel, ship.RepairSteel, bucketUsed ? "高速修復材x1" : ("修理完了予定: " + DateTimeHelper.TimeToCSVString(DateTime.Now + TimeSpan.FromMilliseconds(ship.RepairTime))) )); From 5574bd450c714a4a1ed7874cec2c01ff0519674b Mon Sep 17 00:00:00 2001 From: Andante Date: Sun, 11 Feb 2018 23:20:57 +0900 Subject: [PATCH 12/12] Version 3.0.7 Release --- ElectronicObserver/Utility/SoftwareInformation.cs | 6 +++--- README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ElectronicObserver/Utility/SoftwareInformation.cs b/ElectronicObserver/Utility/SoftwareInformation.cs index 68a2a573d..4e0186bd8 100644 --- a/ElectronicObserver/Utility/SoftwareInformation.cs +++ b/ElectronicObserver/Utility/SoftwareInformation.cs @@ -29,20 +29,20 @@ public static class SoftwareInformation /// /// バージョン(日本語, ソフトウェア名を含みます) /// - public static string VersionJapanese => SoftwareNameJapanese + "三〇型改六甲"; + public static string VersionJapanese => SoftwareNameJapanese + "三〇型改七"; /// /// バージョン(英語) /// - public static string VersionEnglish => "3.0.6.1"; + public static string VersionEnglish => "3.0.7"; /// /// 更新日時 /// - public static DateTime UpdateTime => DateTimeHelper.CSVStringToTime("2017/12/13 09:00:00"); + public static DateTime UpdateTime => DateTimeHelper.CSVStringToTime("2018/02/11 23:00:00"); diff --git a/README.md b/README.md index 53181a9d3..dfb5c1d49 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ *このリンクの更新は遅れる可能性があります。最新版は[こちら](http://electronicobserver.blog.fc2.com/)で確認してください。* -[ver. 3.0.6.1 (2017/12/13)](http://bit.ly/2iZu4eV) +[ver. 3.0.7 (2018/02/11)](http://bit.ly/2EyHZFa) [更新内容・履歴はこちらで確認できます。](https://github.com/andanteyk/ElectronicObserver/wiki/ChangeLog)