\r
namespace KancolleSniffer\r
{\r
- public struct ChargeStatus\r
- {\r
- public int Fuel { get; set; }\r
- public int Bull { get; set; }\r
-\r
- public ChargeStatus(ShipStatus status) : this()\r
- {\r
- Fuel = CalcChargeState(status.Fuel, status.Spec.FuelMax);\r
- Bull = CalcChargeState(status.Bull, status.Spec.BullMax);\r
- }\r
-\r
- public ChargeStatus(int fuel, int bull) : this()\r
- {\r
- Fuel = fuel;\r
- Bull = bull;\r
- }\r
-\r
- private int CalcChargeState(int now, int full)\r
- {\r
- if (full == 0 || now == full)\r
- return 0;\r
- var ratio = (double)now / full;\r
- if (ratio >= 7.0 / 9)\r
- return 1;\r
- if (ratio >= 3.0 / 9)\r
- return 2;\r
- if (ratio > 0)\r
- return 3;\r
- return 4;\r
- }\r
- }\r
-\r
- public enum FleetState\r
- {\r
- Port,\r
- Mission,\r
- Sortie,\r
- Practice\r
- }\r
-\r
- public class Fleet\r
- {\r
- public FleetState State { get; set; }\r
- public int[] Deck { get; set; } = Enumerable.Repeat(-1, ShipInfo.MemberCount).ToArray();\r
- }\r
\r
public class ShipInfo\r
{\r
public const int FleetCount = 4;\r
public const int MemberCount = 6;\r
\r
- private readonly Fleet[] _fleets = Enumerable.Range(0, FleetCount).Select(x => new Fleet()).ToArray();\r
+ private readonly Fleet[] _fleets;\r
private readonly Dictionary<int, ShipStatus> _shipInfo = new Dictionary<int, ShipStatus>();\r
private readonly ShipMaster _shipMaster = new ShipMaster();\r
private readonly ItemInfo _itemInfo;\r
- private int _hqLevel;\r
private readonly List<int> _escapedShips = new List<int>();\r
private int _combinedFleetType;\r
private ShipStatus[] _battleResult = new ShipStatus[0];\r
+ public int HqLevel { get; private set; }\r
public ShipStatusPair[] BattleResultDiff { get; private set; } = new ShipStatusPair[0];\r
public bool IsBattleResultError => BattleResultDiff.Length > 0;\r
public ShipStatus[] BattleStartStatus { get; private set; } = new ShipStatus[0];\r
\r
public ShipInfo(ItemInfo itemInfo)\r
{\r
+ _fleets = Enumerable.Range(0, FleetCount).Select(x => new Fleet(this)).ToArray();\r
_itemInfo = itemInfo;\r
ClearShipInfo();\r
}\r
\r
private void InspectBasic(dynamic json)\r
{\r
- _hqLevel = (int)json.api_level;\r
+ HqLevel = (int)json.api_level;\r
}\r
\r
public void InspectCharge(dynamic json)\r
s.Cond = Max(40, s.Cond);\r
}\r
\r
- public ShipStatus[] GetShipStatuses(int fleet)\r
- {\r
- return _fleets[fleet].Deck.Where(id => id != -1).Select(GetStatus).ToArray();\r
- }\r
-\r
public Fleet[] Fleets => _fleets;\r
\r
public ShipStatus GetStatus(int id)\r
\r
public ShipStatus[] ShipList => _shipInfo.Keys.Where(id => id != -1).Select(GetStatus).ToArray();\r
\r
- public ChargeStatus[] ChargeStatuses\r
- => (from fleet in _fleets\r
- let flag = new ChargeStatus(_shipInfo[fleet.Deck[0]])\r
- let others = (from id in fleet.Deck.Skip(1)\r
- select new ChargeStatus(_shipInfo[id]))\r
- .Aggregate(\r
- (result, next) =>\r
- new ChargeStatus(Max(result.Fuel, next.Fuel), Max(result.Bull, next.Bull)))\r
- select new ChargeStatus(flag.Fuel != 0 ? flag.Fuel : others.Fuel + 5,\r
- flag.Bull != 0 ? flag.Bull : others.Bull + 5)).ToArray();\r
-\r
- public int[] GetFighterPower(int fleet)\r
- => GetShipStatuses(fleet).Where(ship => !ship.Escaped).SelectMany(ship =>\r
- ship.Slot.Zip(ship.OnSlot, (slot, onslot) => slot.CalcFighterPower(onslot)))\r
- .Aggregate(new[] {0, 0}, (prev, cur) => new[] {prev[0] + cur[0], prev[1] + cur[1]});\r
-\r
- public double GetContactTriggerRate(int fleet)\r
- => GetShipStatuses(fleet).Where(ship => !ship.Escaped).SelectMany(ship =>\r
- ship.Slot.Zip(ship.OnSlot, (slot, onslot) =>\r
- slot.Spec.ContactTriggerRate * slot.Spec.LoS * Sqrt(onslot))).Sum();\r
-\r
public ShipStatus[] GetRepairList(DockInfo dockInfo)\r
=> (from s in ShipList\r
where s.NowHp < s.MaxHp && !dockInfo.InNDock(s.Id)\r
select s).OrderByDescending(s => s.RepairTime).ToArray();\r
\r
- public double GetLineOfSights(int fleet, int factor)\r
- {\r
- var result = 0.0;\r
- var emptyBonus = 6;\r
- foreach (var s in GetShipStatuses(fleet).Where(s => !s.Escaped))\r
- {\r
- emptyBonus--;\r
- var itemLoS = 0;\r
- foreach (var item in s.Slot)\r
- {\r
- var spec = item.Spec;\r
- itemLoS += spec.LoS;\r
- result += (spec.LoS + item.LoSLevelBonus) * spec.LoSScaleFactor * factor;\r
- }\r
- result += Sqrt(s.LoS - itemLoS);\r
- }\r
- return result > 0 ? result - Ceiling(_hqLevel * 0.4) + emptyBonus * 2 : 0.0;\r
- }\r
-\r
- public double GetDaihatsuBonus(int fleet)\r
- {\r
- var tokudaiBonus = new[,]\r
- {\r
- {0.00, 0.00, 0.00, 0.00, 0.00},\r
- {0.02, 0.02, 0.02, 0.02, 0.02},\r
- {0.04, 0.04, 0.04, 0.04, 0.04},\r
- {0.05, 0.05, 0.052, 0.054, 0.054},\r
- {0.054, 0.056, 0.058, 0.059, 0.06}\r
- };\r
- var daihatsu = 0;\r
- var tokudai = 0;\r
- var bonus = 0.0;\r
- var level = 0;\r
- var sum = 0;\r
- foreach (var ship in GetShipStatuses(fleet))\r
- {\r
- if (ship.Name == "鬼怒改二")\r
- bonus += 0.05;\r
- foreach (var item in ship.Slot)\r
- {\r
- switch (item.Spec.Name)\r
- {\r
- case "大発動艇":\r
- level += item.Level;\r
- sum++;\r
- daihatsu++;\r
- bonus += 0.05;\r
- break;\r
- case "特大発動艇":\r
- level += item.Level;\r
- sum++;\r
- tokudai++;\r
- bonus += 0.05;\r
- break;\r
- case "大発動艇(八九式中戦車&陸戦隊)":\r
- level += item.Level;\r
- sum++;\r
- bonus += 0.02;\r
- break;\r
- case "特二式内火艇":\r
- level += item.Level;\r
- sum++;\r
- bonus += 0.01;\r
- break;\r
- }\r
- }\r
- }\r
- var levelAverage = sum == 0 ? 0.0 : (double)level / sum;\r
- bonus = Min(bonus, 0.2);\r
- return bonus + 0.01 * bonus * levelAverage + tokudaiBonus[Min(tokudai, 4), Min(daihatsu, 4)];\r
- }\r
-\r
- public double GetTransportPoint(int fleet)\r
- {\r
- return GetShipStatuses(fleet).Where(ship => !ship.Escaped).Sum(ship => ship.TransportPoint);\r
- }\r
-\r
public string[] BadlyDamagedShips { get; private set; } = new string[0];\r
\r
public void SetBadlyDamagedShips()\r