OSDN Git Service

敵の制空値を表示する
authorKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Fri, 25 Jul 2014 08:55:31 +0000 (17:55 +0900)
committerKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Sun, 27 Jul 2014 06:28:00 +0000 (15:28 +0900)
KancolleSniffer/BattleInfo.cs
KancolleSniffer/ItemInfo.cs
KancolleSniffer/MainForm.Designer.cs
KancolleSniffer/MainForm.cs
KancolleSniffer/MainForm.resx
KancolleSniffer/ShipMaster.cs
KancolleSniffer/Sniffer.cs

index f4c379a..ff99d4a 100644 (file)
@@ -15,6 +15,7 @@
 // You should have received a copy of the GNU General Public License\r
 // along with this program; if not, see <http://www.gnu.org/licenses/>.\r
 \r
+using System;\r
 using System.Linq;\r
 \r
 namespace KancolleSniffer\r
@@ -23,18 +24,23 @@ namespace KancolleSniffer
     {\r
         private readonly ShipMaster _shipMaster;\r
         private readonly ShipInfo _shipInfo;\r
+        private readonly ItemInfo _itemInfo;\r
         public bool InBattle { get; set; }\r
         public string Formation { get; private set; }\r
         public int DelayInFormation { get; private set; }\r
+        public int EnemyAirSuperiority { get; private set; }\r
+        public int DelayInAirSuperiority { get; private set; }\r
 \r
         private struct Delay\r
         {\r
-            public const int Basic = 7200;\r
+            public const int Basic = 4100;\r
+            public const int Formation = 1100;\r
             public const int Tau = 200;\r
             public const int SearchAirSuccess = 5700;\r
             public const int SearchAirFailure = 4900;\r
             public const int SearchSuccess = 5400;\r
             public const int Submarine = 2500;\r
+            public const int Emergence = 2000;\r
             public const int AirFight = 8700;\r
             public const int AirFightBoth = 2700;\r
             public const int Support = 9800;\r
@@ -42,53 +48,70 @@ namespace KancolleSniffer
             public const int Cutin = 4900;\r
         }\r
 \r
-        public BattleInfo(ShipMaster shipMaster, ShipInfo shipInfo)\r
+        public BattleInfo(ShipMaster shipMaster, ShipInfo shipInfo, ItemInfo itemInfo)\r
         {\r
             _shipMaster = shipMaster;\r
             _shipInfo = shipInfo;\r
+            _itemInfo = itemInfo;\r
         }\r
 \r
         public void InspectBattle(dynamic json)\r
         {\r
             InBattle = true;\r
-            var delay = Delay.Basic;\r
+            Formation = FormationName(json);\r
+            EnemyAirSuperiority = CalcEnemyAirSuperiority(json);\r
+            SetDelay(json);\r
+        }\r
+\r
+        private string FormationName(dynamic json)\r
+        {\r
             switch ((int)json.api_formation[2])\r
             {\r
                 case 1:\r
-                    Formation = "同航戦";\r
-                    break;\r
+                    return "同航戦";\r
                 case 2:\r
-                    Formation = "反航戦";\r
-                    break;\r
+                    return "反航戦";\r
                 case 3:\r
-                    Formation = "T字有利";\r
-                    delay += Delay.Tau;\r
-                    break;\r
+                    return "T字有利";\r
                 case 4:\r
-                    Formation = "T字不利";\r
-                    delay += Delay.Tau;\r
-                    break;\r
+                    return "T字不利";\r
             }\r
+            return "";\r
+        }\r
+\r
+        private void SetDelay(dynamic json)\r
+        {\r
+            // 敵出現まで\r
+            var delay = Delay.Basic;\r
+            if ((int)json.api_formation[2] >= 3)\r
+                delay += Delay.Tau;\r
             var subm = (SubmarineFlags)CheckSubmarine(json);\r
-            delay += SearchDelay(json) + SupportDelay(json) + CutinDelay(json) + subm.SubmarineDelay();\r
-            if (!subm.PreventOpeningAttack)\r
-                delay += OpeningAttackDelay(json);\r
+            bool success;\r
+            delay += SearchDelay(json, out success) + subm.AddtionalDelay;\r
+            DelayInAirSuperiority = delay + (success ? 0 : Delay.Emergence); // 失敗すると出現が遅れる\r
+            // 敵艦隊発見以降\r
+            delay += Delay.Emergence + Delay.Formation + SupportDelay(json) + CutinDelay(json);\r
             if (!subm.PreventAirFight)\r
                 delay += AirFightDelay(json);\r
+            if (!subm.PreventOpeningAttack)\r
+                delay += OpeningAttackDelay(json);\r
             DelayInFormation = delay;\r
         }\r
 \r
-        private int SearchDelay(dynamic json)\r
+        private int SearchDelay(dynamic json, out bool success)\r
         {\r
+            success = false;\r
             switch ((int)json.api_search[0])\r
             {\r
                 case 1: // 索敵機による索敵成功\r
                 case 2: // 索敵機未帰還あり\r
+                    success = true;\r
                     return Delay.SearchAirSuccess;\r
                 case 3: // 索敵機未帰還\r
                 case 4: // 索敵機による索敵失敗\r
                     return Delay.SearchAirFailure;\r
                 case 5: // 索敵力による索敵成功\r
+                    success = true;\r
                     return Delay.SearchSuccess;\r
             }\r
             return 0;\r
@@ -104,9 +127,10 @@ namespace KancolleSniffer
             public bool[] Friend;\r
             public bool[] Enemy;\r
 \r
-            public int SubmarineDelay()\r
+            public int AddtionalDelay\r
             {\r
-                return Friend.Any(x => x) || Enemy.Any(x => x) ? Delay.Submarine : 0; // どちらかに潜水艦                \r
+                get { return Friend.Any(x => x) || Enemy.Any(x => x) ? Delay.Submarine : 0; }\r
+                // どちらかに潜水艦                \r
             }\r
 \r
             public bool PreventAirFight\r
@@ -186,5 +210,13 @@ namespace KancolleSniffer
             }\r
             return false;\r
         }\r
+\r
+        private int CalcEnemyAirSuperiority(dynamic json)\r
+        {\r
+            var maxEq = ((int[])json.api_ship_ke).Skip(1).SelectMany(id => _shipMaster[id].MaxEq);\r
+            var equips = ((int[][])json.api_eSlot).SelectMany(x => x);\r
+            return (from slot in equips.Zip(maxEq, (id, max) => new {id, max})\r
+                select (int)Math.Floor(_itemInfo.GetSpecByItemId(slot.id).TyKu * Math.Sqrt(slot.max))).Sum();\r
+        }\r
     }\r
 }
\ No newline at end of file
index 6fe83d2..d91d622 100644 (file)
@@ -135,5 +135,10 @@ namespace KancolleSniffer
         {\r
             return _itemSpecs[_itemIds[id]];\r
         }\r
+\r
+        public ItemSpec GetSpecByItemId(int id)\r
+        {\r
+            return _itemSpecs[id];\r
+        }\r
     }\r
 }
\ No newline at end of file
index 94cb33a..d0905e7 100644 (file)
@@ -59,6 +59,11 @@ namespace KancolleSniffer
             this.labelNumOfShips = new System.Windows.Forms.Label();\r
             this.label1 = new System.Windows.Forms.Label();\r
             this.panelFleet1 = new System.Windows.Forms.Panel();\r
+            this.panelBattleInfo = new System.Windows.Forms.Panel();\r
+            this.labelEnemyAirSuperiority = new System.Windows.Forms.Label();\r
+            this.label30 = new System.Windows.Forms.Label();\r
+            this.labelFormation = new System.Windows.Forms.Label();\r
+            this.label29 = new System.Windows.Forms.Label();\r
             this.label19 = new System.Windows.Forms.Label();\r
             this.labelAkashiTimer = new System.Windows.Forms.Label();\r
             this.labelAirSuperiority = new System.Windows.Forms.Label();\r
@@ -179,18 +184,15 @@ namespace KancolleSniffer
             this.labelFleet3 = new System.Windows.Forms.Label();\r
             this.labelCheckFleet2 = new System.Windows.Forms.Label();\r
             this.labelFleet2 = new System.Windows.Forms.Label();\r
-            this.panelBattleInfo = new System.Windows.Forms.Panel();\r
-            this.label29 = new System.Windows.Forms.Label();\r
-            this.labelFormation = new System.Windows.Forms.Label();\r
             this.panelHeadquarters.SuspendLayout();\r
             this.panelFleet1.SuspendLayout();\r
+            this.panelBattleInfo.SuspendLayout();\r
             this.panelDock.SuspendLayout();\r
             this.panel1.SuspendLayout();\r
             this.panel2.SuspendLayout();\r
             this.panel3.SuspendLayout();\r
             this.contextMenuStripToolTip.SuspendLayout();\r
             this.panel4.SuspendLayout();\r
-            this.panelBattleInfo.SuspendLayout();\r
             this.SuspendLayout();\r
             // \r
             // panelHeadquarters\r
@@ -356,6 +358,51 @@ namespace KancolleSniffer
             this.panelFleet1.Size = new System.Drawing.Size(245, 136);\r
             this.panelFleet1.TabIndex = 2;\r
             // \r
+            // panelBattleInfo\r
+            // \r
+            this.panelBattleInfo.Controls.Add(this.labelEnemyAirSuperiority);\r
+            this.panelBattleInfo.Controls.Add(this.label30);\r
+            this.panelBattleInfo.Controls.Add(this.labelFormation);\r
+            this.panelBattleInfo.Controls.Add(this.label29);\r
+            this.panelBattleInfo.Location = new System.Drawing.Point(66, 119);\r
+            this.panelBattleInfo.Name = "panelBattleInfo";\r
+            this.panelBattleInfo.Size = new System.Drawing.Size(175, 12);\r
+            this.panelBattleInfo.TabIndex = 40;\r
+            this.panelBattleInfo.Visible = false;\r
+            // \r
+            // labelEnemyAirSuperiority\r
+            // \r
+            this.labelEnemyAirSuperiority.Location = new System.Drawing.Point(141, 0);\r
+            this.labelEnemyAirSuperiority.Name = "labelEnemyAirSuperiority";\r
+            this.labelEnemyAirSuperiority.Size = new System.Drawing.Size(23, 12);\r
+            this.labelEnemyAirSuperiority.TabIndex = 3;\r
+            this.labelEnemyAirSuperiority.TextAlign = System.Drawing.ContentAlignment.MiddleRight;\r
+            // \r
+            // label30\r
+            // \r
+            this.label30.AutoSize = true;\r
+            this.label30.Location = new System.Drawing.Point(99, 0);\r
+            this.label30.Name = "label30";\r
+            this.label30.Size = new System.Drawing.Size(41, 12);\r
+            this.label30.TabIndex = 2;\r
+            this.label30.Text = "敵制空";\r
+            // \r
+            // labelFormation\r
+            // \r
+            this.labelFormation.Location = new System.Drawing.Point(44, 0);\r
+            this.labelFormation.Name = "labelFormation";\r
+            this.labelFormation.Size = new System.Drawing.Size(48, 12);\r
+            this.labelFormation.TabIndex = 1;\r
+            // \r
+            // label29\r
+            // \r
+            this.label29.AutoSize = true;\r
+            this.label29.Location = new System.Drawing.Point(1, 0);\r
+            this.label29.Name = "label29";\r
+            this.label29.Size = new System.Drawing.Size(41, 12);\r
+            this.label29.TabIndex = 0;\r
+            this.label29.Text = "交戦形";\r
+            // \r
             // label19\r
             // \r
             this.label19.AutoSize = true;\r
@@ -1447,32 +1494,6 @@ namespace KancolleSniffer
             this.labelFleet2.Text = "第二艦隊";\r
             this.labelFleet2.Click += new System.EventHandler(this.labelFleet_Click);\r
             // \r
-            // panelBattleInfo\r
-            // \r
-            this.panelBattleInfo.Controls.Add(this.labelFormation);\r
-            this.panelBattleInfo.Controls.Add(this.label29);\r
-            this.panelBattleInfo.Location = new System.Drawing.Point(66, 119);\r
-            this.panelBattleInfo.Name = "panelBattleInfo";\r
-            this.panelBattleInfo.Size = new System.Drawing.Size(175, 12);\r
-            this.panelBattleInfo.TabIndex = 40;\r
-            this.panelBattleInfo.Visible = false;\r
-            // \r
-            // label29\r
-            // \r
-            this.label29.AutoSize = true;\r
-            this.label29.Location = new System.Drawing.Point(1, 0);\r
-            this.label29.Name = "label29";\r
-            this.label29.Size = new System.Drawing.Size(41, 12);\r
-            this.label29.TabIndex = 0;\r
-            this.label29.Text = "戦闘中";\r
-            // \r
-            // labelFormation\r
-            // \r
-            this.labelFormation.Location = new System.Drawing.Point(44, 0);\r
-            this.labelFormation.Name = "labelFormation";\r
-            this.labelFormation.Size = new System.Drawing.Size(48, 12);\r
-            this.labelFormation.TabIndex = 1;\r
-            // \r
             // MainForm\r
             // \r
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\r
@@ -1510,6 +1531,8 @@ namespace KancolleSniffer
             this.panelHeadquarters.PerformLayout();\r
             this.panelFleet1.ResumeLayout(false);\r
             this.panelFleet1.PerformLayout();\r
+            this.panelBattleInfo.ResumeLayout(false);\r
+            this.panelBattleInfo.PerformLayout();\r
             this.panelDock.ResumeLayout(false);\r
             this.panelDock.PerformLayout();\r
             this.panel1.ResumeLayout(false);\r
@@ -1520,8 +1543,6 @@ namespace KancolleSniffer
             this.contextMenuStripToolTip.ResumeLayout(false);\r
             this.panel4.ResumeLayout(false);\r
             this.panel4.PerformLayout();\r
-            this.panelBattleInfo.ResumeLayout(false);\r
-            this.panelBattleInfo.PerformLayout();\r
             this.ResumeLayout(false);\r
             this.PerformLayout();\r
 \r
@@ -1664,6 +1685,8 @@ namespace KancolleSniffer
         private System.Windows.Forms.Panel panelBattleInfo;\r
         private System.Windows.Forms.Label labelFormation;\r
         private System.Windows.Forms.Label label29;\r
+        private System.Windows.Forms.Label labelEnemyAirSuperiority;\r
+        private System.Windows.Forms.Label label30;\r
     }\r
 }\r
 \r
index 2b6b49d..39b99e9 100644 (file)
@@ -119,7 +119,6 @@ namespace KancolleSniffer
             Application.Exit();\r
         }\r
 \r
-\r
         private void ConfigToolStripMenuItem_Click(object sender, EventArgs e)\r
         {\r
             if (_configDialog.ShowDialog(this) == DialogResult.OK)\r
@@ -207,16 +206,24 @@ namespace KancolleSniffer
         private void UpdateBattleInfo()\r
         {\r
             labelFormation.Text = "";\r
+            labelEnemyAirSuperiority.Text = "";\r
             panelBattleInfo.Visible = _sniffer.Battle.InBattle;\r
             if (!_sniffer.Battle.InBattle)\r
                 return;\r
-            var timer = new Timer {Interval = _sniffer.Battle.DelayInFormation};\r
-            timer.Tick += (sender, args) =>\r
+            var tf = new Timer {Interval = _sniffer.Battle.DelayInFormation};\r
+            tf.Tick += (sender, args) =>\r
             {\r
                 labelFormation.Text = _sniffer.Battle.Formation;\r
-                timer.Stop();\r
+                tf.Stop();\r
+            };\r
+            tf.Start();\r
+            var ta = new Timer {Interval = _sniffer.Battle.DelayInAirSuperiority};\r
+            ta.Tick += (sender, args) =>\r
+            {\r
+                labelEnemyAirSuperiority.Text = _sniffer.Battle.EnemyAirSuperiority.ToString("D");\r
+                ta.Stop();\r
             };\r
-            timer.Start();\r
+            ta.Start();\r
         }\r
 \r
         private void UpdateChargeInfo()\r
index 06e3225..4bd54a8 100644 (file)
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\r
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\r
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAQ\r
-        CwAAAk1TRnQBSQFMAgEBBQEAASgBAAEoAQABDgEAAQ8BAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
+        CwAAAk1TRnQBSQFMAgEBBQEAATgBAAE4AQABDgEAAQ8BAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
         AwABOAMAAR4DAAEBAQABCAUAAZABBhgAAYACAAGAAwACgAEAAYADAAGAAQABgAEAAoACAAPAAQABwAHc\r
         AcABAAHwAcoBpgEAATMFAAEzAQABMwEAATMBAAIzAgADFgEAAxwBAAMiAQADKQEAA1UBAANNAQADQgEA\r
         AzkBAAGAAXwB/wEAAlAB/wEAAZMBAAHWAQAB/wHsAcwBAAHGAdYB7wEAAdYC5wEAAZABqQGtAgAB/wEz\r
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\r
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\r
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA0\r
-        CwAAAk1TRnQBSQFMAgEBBQEAASgBAAEoAQABDgEAAQ4BAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
+        CwAAAk1TRnQBSQFMAgEBBQEAATgBAAE4AQABDgEAAQ4BAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
         AwABOAMAARwDAAEBAQABCAUAASABBhgAAYACAAGAAwACgAEAAYADAAGAAQABgAEAAoACAAPAAQABwAHc\r
         AcABAAHwAcoBpgEAATMFAAEzAQABMwEAATMBAAIzAgADFgEAAxwBAAMiAQADKQEAA1UBAANNAQADQgEA\r
         AzkBAAGAAXwB/wEAAlAB/wEAAZMBAAHWAQAB/wHsAcwBAAHGAdYB7wEAAdYC5wEAAZABqQGtAgAB/wEz\r
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\r
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\r
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABm\r
-        BwAAAk1TRnQBSQFMAwEBAAFgAQABYAEAAQcBAAEPAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA\r
+        BwAAAk1TRnQBSQFMAwEBAAFwAQABcAEAAQcBAAEPAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA\r
         ARwDAAEPAwABAQEAAQgFAAGkAQEYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA\r
         AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5\r
         AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA\r
index 9115e85..6199fd1 100644 (file)
@@ -21,6 +21,7 @@ namespace KancolleSniffer
 {\r
     public class ShipMaster\r
     {\r
+        public const int NumSlots = 5;\r
         private readonly Dictionary<int, ShipSpec> _shipSpecs = new Dictionary<int, ShipSpec>();\r
 \r
         public void Inspect(dynamic json)\r
@@ -32,10 +33,11 @@ namespace KancolleSniffer
                     Name = entry.api_name,\r
                     FuelMax = (int)entry.api_fuel_max,\r
                     BullMax = (int)entry.api_bull_max,\r
+                    MaxEq = (int[])entry.api_maxeq,\r
                     ShipType = (int)entry.api_stype,\r
                 };\r
             }\r
-            _shipSpecs[-1] = new ShipSpec {Name = "不明"};\r
+            _shipSpecs[-1] = new ShipSpec {Name = "不明", MaxEq = new int[NumSlots]};\r
         }\r
 \r
         public ShipSpec this[int id]\r
@@ -49,6 +51,7 @@ namespace KancolleSniffer
         public string Name { get; set; }\r
         public int FuelMax { get; set; }\r
         public int BullMax { get; set; }\r
+        public int[] MaxEq { get; set; }\r
         public int ShipType { get; set; }\r
 \r
         public bool IsSubmarine\r
index 30326e9..5d0fce9 100644 (file)
@@ -53,7 +53,7 @@ namespace KancolleSniffer
             _shipInfo = new ShipInfo(_shipMaster, _itemInfo);\r
             _dockInfo = new DockInfo(_shipInfo);\r
             _akashiTimer = new AkashiTimer(_shipInfo, _itemInfo, _dockInfo, _missionInfo);\r
-            _battleInfo = new BattleInfo(_shipMaster, _shipInfo);\r
+            _battleInfo = new BattleInfo(_shipMaster, _shipInfo, _itemInfo);\r
         }\r
 \r
         public void SaveState()\r