Skip to content

Commit

Permalink
34-2 のようなランダムボス編成に対応したつもり
Browse files Browse the repository at this point in the history
  • Loading branch information
veigr committed May 3, 2016
1 parent 0effc0c commit 578ec20
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 114 deletions.
1 change: 1 addition & 0 deletions EventMapHpViewer/EventMapHpViewer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<Compile Include="Models\Raw\map_select_eventmap_rank.cs" />
<Compile Include="Models\Raw\member_mapinfo.cs" />
<Compile Include="Models\Raw\map_start_next.cs" />
<Compile Include="Models\RemainingCount.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ToolView.xaml.cs">
<DependentUpon>ToolView.xaml</DependentUpon>
Expand Down
2 changes: 1 addition & 1 deletion EventMapHpViewer/MapHpViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace EventMapHpViewer
public class MapHpViewer : IPlugin, ITool
{
internal const string title = "MapHPViewer";
internal const string version = "3.1.2";
internal const string version = "3.2.0";
private ToolViewModel vm;

public void Initialize()
Expand Down
127 changes: 44 additions & 83 deletions EventMapHpViewer/Models/MapData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
Expand Down Expand Up @@ -41,92 +41,94 @@ public int Current
{
get
{
if (this.IsExBoss == 1) return this.Master.RequiredDefeatCount - this.DefeatCount; //ゲージ有り通常海域
return this.Eventmap?.NowMapHp /*イベント海域*/?? 1 /*ゲージ無し通常海域*/;
if (this.IsExBoss == 1) return this.Master.RequiredDefeatCount - this.DefeatCount; //ゲージ有り通常海域
return this.Eventmap?.NowMapHp /*イベント海域*/?? 1 /*ゲージ無し通常海域*/;
}
}

private int[] remoteBossHpCache;
private Raw.map_exboss[] remoteBossDataCache;

/// <summary>
/// 残回数。輸送の場合はA勝利の残回数。
/// 残回数。輸送の場合はA勝利の残回数。
/// </summary>
public async Task<int> GetRemainingCount(bool useCache = false)
public async Task<RemainingCount> GetRemainingCount(bool useCache = false)
{
if (this.IsCleared == 1) return 0;
if (this.IsCleared == 1) return RemainingCount.Zero;

if (this.IsExBoss == 1) return this.Current; //ゲージ有り通常海域
if (this.IsExBoss == 1) return new RemainingCount(this.Current); //ゲージ有り通常海域

if (this.Eventmap == null) return 1; //ゲージ無し通常海域
if (this.Eventmap == null) return new RemainingCount(1); //ゲージ無し通常海域

if (this.Eventmap.GaugeType == GaugeType.Transport)
{
var capacityA = KanColleClient.Current.Homeport.Organization.TransportationCapacity();
if (capacityA == 0) return int.MaxValue; //ゲージ減らない
return (int)Math.Ceiling((double)this.Current / capacityA);
if (capacityA == 0) return RemainingCount.MaxValue; //ゲージ減らない
return new RemainingCount((int)Math.Ceiling((double)this.Current / capacityA));
}

if (this.Eventmap.SelectedRank == 0) return -1; //難易度未選択
if (this.Eventmap.SelectedRank == 0) return null; //難易度未選択

if (!useCache)
this.remoteBossHpCache = await GetEventBossHp(this.Id, this.Eventmap.SelectedRank);
this.remoteBossDataCache = await GetEventBossHp(this.Id, this.Eventmap.SelectedRank);

if (this.remoteBossDataCache != null && this.remoteBossDataCache.Any())
return this.CalculateRemainingCount(this.remoteBossDataCache); //イベント海域(リモートデータ)

var remoteBossHp = this.remoteBossHpCache;
if (remoteBossHp != null && remoteBossHp.Any())
return this.CalculateRemainingCount(remoteBossHp); //イベント海域(リモートデータ)
return null; //未対応
}

try
{
// リモートデータがない場合、ローカルデータを使う
return this.CalculateRemainingCount(eventBossHpDictionary[this.Eventmap.SelectedRank][this.Id]); //イベント海域
}
catch (KeyNotFoundException)
{
return -1; //未対応
}
private RemainingCount CalculateRemainingCount(Raw.map_exboss[] data)
{
return new RemainingCount(
CalculateRemainingCount(
data.Where(x => !x.isLast).Min(x => x.ship.maxhp),
data.Where(x => x.isLast).Min(x => x.ship.maxhp)
),
CalculateRemainingCount(
data.Where(x => !x.isLast).Max(x => x.ship.maxhp),
data.Where(x => x.isLast).Max(x => x.ship.maxhp)
));
}

private int CalculateRemainingCount(int[] bossHPs)
private int CalculateRemainingCount(int normalBossHp, int lastBossHp)
{
var lastBossHp = bossHPs.Last();
var normalBossHp = bossHPs.First();
if (this.Current <= lastBossHp) return 1; //最後の1回
if (this.Current <= lastBossHp) return 1; //最後の1回
return (int)Math.Ceiling((double)(this.Current - lastBossHp) / normalBossHp) + 1;
}

/// <summary>
/// 輸送ゲージのS勝利時の残回数
/// 輸送ゲージのS勝利時の残回数
/// </summary>
public int RemainingCountTransportS
{
get
{
if (this.Eventmap?.GaugeType != GaugeType.Transport) return -1;
var capacity = KanColleClient.Current.Homeport.Organization.TransportationCapacity(true);
if (capacity == 0) return int.MaxValue; //ゲージ減らない
if (capacity == 0) return int.MaxValue; //ゲージ減らない
return (int)Math.Ceiling((double)this.Current / capacity);
}
}

/// <summary>
/// 艦これ戦術データ・リンクからボス情報を取得する。
/// 取得できなかった場合は null を返す。
/// 艦これ戦術データ・リンクからボス情報を取得する。
/// 取得できなかった場合は null を返す。
/// </summary>
/// <param name="mapId"></param>
/// <param name="rank"></param>
/// <returns></returns>
private static async Task<int[]> GetEventBossHp(int mapId, int rank)
private static async Task<Raw.map_exboss[]> GetEventBossHp(int mapId, int rank)
{
using (var client = new HttpClient(GetProxyConfiguredHandler()))
{
client.DefaultRequestHeaders
.TryAddWithoutValidation("User-Agent", $"{MapHpViewer.title}/{MapHpViewer.version}");
try {
// rank の後ろの"1"はサーバー上手動メンテデータを加味するかどうかのフラグ
var response = await client.GetAsync($"https://kctadil.azurewebsites.net/map/exboss/{mapId}/{rank}/1");
// rank の後ろの"1"はサーバー上手動メンテデータを加味するかどうかのフラグ
var response = await client.GetAsync($"https://kctadil.azurewebsites.net/map/maphp/v3.2/{mapId}/{rank}");
if (!response.IsSuccessStatusCode)
{
// 200 じゃなかった
// 200 じゃなかった
return null;
}

Expand All @@ -136,24 +138,21 @@ private static async Task<int[]> GetEventBossHp(int mapId, int rank)
|| !parsed.Any(x => x.isLast)
|| !parsed.Any(x => !x.isLast))
{
// データが揃っていない
// データが揃っていない
return null;
}
return parsed
.OrderBy(x => x.isLast) // 最終編成が後ろに来るようにする
.Select(x => x.ship.maxhp)
.ToArray();
return parsed;
}
catch (HttpRequestException)
{
// HTTP リクエストに失敗した
// HTTP リクエストに失敗した
return null;
}
}
}

/// <summary>
/// 本体のプロキシ設定を組み込んだHttpClientHandlerを返す。
/// 本体のプロキシ設定を組み込んだHttpClientHandlerを返す。
/// </summary>
/// <returns></returns>
private static HttpClientHandler GetProxyConfiguredHandler()
Expand Down Expand Up @@ -187,43 +186,5 @@ private static HttpClientHandler GetProxyConfiguredHandler()
return new HttpClientHandler();
}
}

/// <summary>
/// 手動メンテデータ用。
/// いずれ削除される見込み。
/// </summary>
private static readonly IReadOnlyDictionary<int, IReadOnlyDictionary<int, int[]>> eventBossHpDictionary
= new Dictionary<int, IReadOnlyDictionary<int, int[]>>
{
{ //難易度未選択
0, new Dictionary<int, int[]>
{
}
},
{ //丙
1, new Dictionary<int, int[]>
{
{ 331, new[] { 110 } },
{ 332, new[] { 600, 380 } },
{ 333, new[] { 350, 370 } },
}
},
{ //乙
2, new Dictionary<int, int[]>
{
{ 331, new[] { 110, 130 } },
{ 332, new[] { 600, 430 } },
{ 333, new[] { 350, 380 } },
}
},
{ //甲
3, new Dictionary<int, int[]>
{
{ 331, new[] { 130, 160 } },
{ 332, new[] { 600, 480 } },
{ 333, new[] { 350, 390 } },
}
},
};
}
}
}
2 changes: 1 addition & 1 deletion EventMapHpViewer/Models/MapInfoProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public MapInfoProxy()
.TryParse<map_select_eventmap_rank>()
.Subscribe(x =>
{
Debug.WriteLine("MapInfoProxy - member_mapinfo");
Debug.WriteLine("MapInfoProxy - select_eventmap_rank");
this.Maps.MapList = this.UpdateRank(x);
this.RaisePropertyChanged(() => this.Maps);
});
Expand Down
72 changes: 72 additions & 0 deletions EventMapHpViewer/Models/RemainingCount.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EventMapHpViewer.Models
{
public class RemainingCount
{
public int Min { get; set; }
public int Max { get; set; }

public RemainingCount()
{
this.Min = 0;
this.Max = 0;
}
public RemainingCount(int min, int max)
{
this.Min = min;
this.Max = max;
}
public RemainingCount(int value)
{
this.Min = value;
this.Max = value;
}

public bool IsSingleValue => this.Min == this.Max;

public override bool Equals(object obj)
{
return obj is RemainingCount && this.Equals((RemainingCount)obj);
}

public override int GetHashCode()
{
unchecked
{
return (this.Min.GetHashCode() * 397) ^ this.Max.GetHashCode();
}
}

public override string ToString()
{
return $"{this.Min}-{this.Max}";
}

public static bool operator ==(RemainingCount value1, RemainingCount value2)
{
if (ReferenceEquals(value1, value2)) return true;
return value1?.Equals(value2) ?? false;
}

public static bool operator !=(RemainingCount id1, RemainingCount id2)
{
return !(id1 == id2);
}

private bool Equals(RemainingCount other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return this.Min == other.Min
&& this.Max == other.Max;
}

public static readonly RemainingCount MaxValue = new RemainingCount(int.MaxValue);
public static readonly RemainingCount Zero = new RemainingCount(0);
}
}
2 changes: 1 addition & 1 deletion EventMapHpViewer/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@
// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
// 既定値にすることができます:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.1.2.0")]
[assembly: AssemblyVersion("3.2.0.0")]
Loading

0 comments on commit 578ec20

Please sign in to comment.