1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 21:27:24 +08:00

Merge pull request #11163 from bdach/taiko-strong-state-refactor

Refactor taiko's strong state management in hitobject hierarchy
This commit is contained in:
Dean Herbert 2020-12-15 12:24:22 +09:00 committed by GitHub
commit 8ec7a10580
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 219 additions and 159 deletions

View File

@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
createDrawableRuleset();
assertStateAfterResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Idle);
assertStateAfterResult(new JudgementResult(new StrongHitObject(), new TaikoStrongJudgement()) { Type = HitResult.IgnoreMiss }, TaikoMascotAnimationState.Idle);
assertStateAfterResult(new JudgementResult(new Hit.StrongNestedHit(), new TaikoStrongJudgement()) { Type = HitResult.IgnoreMiss }, TaikoMascotAnimationState.Idle);
}
[Test]

View File

@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
IsCentre = (hitObject as Hit)?.Type == HitType.Centre,
IsDrumRoll = hitObject is DrumRoll,
IsSwell = hitObject is Swell,
IsStrong = ((TaikoHitObject)hitObject).IsStrong
IsStrong = (hitObject as TaikoStrongableHitObject)?.IsStrong == true
};
}

View File

@ -65,8 +65,8 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
converted.HitObjects = converted.HitObjects.GroupBy(t => t.StartTime).Select(x =>
{
TaikoHitObject first = x.First();
if (x.Skip(1).Any() && first.CanBeStrong)
first.IsStrong = true;
if (x.Skip(1).Any() && first is TaikoStrongableHitObject strong)
strong.IsStrong = true;
return first;
}).ToList();
}

View File

@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Taiko.Edit
base.UpdateTernaryStates();
selectionRimState.Value = GetStateFromSelection(EditorBeatmap.SelectedHitObjects.OfType<Hit>(), h => h.Type == HitType.Rim);
selectionStrongState.Value = GetStateFromSelection(EditorBeatmap.SelectedHitObjects.OfType<TaikoHitObject>(), h => h.IsStrong);
selectionStrongState.Value = GetStateFromSelection(EditorBeatmap.SelectedHitObjects.OfType<TaikoStrongableHitObject>(), h => h.IsStrong);
}
}
}

View File

@ -19,7 +19,7 @@ using osuTK;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableDrumRoll : DrawableTaikoHitObject<DrumRoll>
public class DrawableDrumRoll : DrawableTaikoStrongableHitObject<DrumRoll, DrumRoll.StrongNestedHit>
{
/// <summary>
/// Number of rolling hits required to reach the dark/final colour.
@ -154,7 +154,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Content.X = DrawHeight / 2;
}
protected override DrawableStrongNestedHit CreateStrongHit(StrongHitObject hitObject) => new StrongNestedHit(hitObject, this);
protected override DrawableStrongNestedHit CreateStrongNestedHit(DrumRoll.StrongNestedHit hitObject) => new StrongNestedHit(hitObject, this);
private void updateColour()
{
@ -164,8 +164,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
private class StrongNestedHit : DrawableStrongNestedHit
{
public StrongNestedHit(StrongHitObject strong, DrawableDrumRoll drumRoll)
: base(strong, drumRoll)
public StrongNestedHit(DrumRoll.StrongNestedHit nestedHit, DrawableDrumRoll drumRoll)
: base(nestedHit, drumRoll)
{
}

View File

@ -9,7 +9,7 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableDrumRollTick : DrawableTaikoHitObject<DrumRollTick>
public class DrawableDrumRollTick : DrawableTaikoStrongableHitObject<DrumRollTick, DrumRollTick.StrongNestedHit>
{
/// <summary>
/// The hit type corresponding to the <see cref="TaikoAction"/> that the user pressed to hit this <see cref="DrawableDrumRollTick"/>.
@ -61,12 +61,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
return UpdateResult(true);
}
protected override DrawableStrongNestedHit CreateStrongHit(StrongHitObject hitObject) => new StrongNestedHit(hitObject, this);
protected override DrawableStrongNestedHit CreateStrongNestedHit(DrumRollTick.StrongNestedHit hitObject) => new StrongNestedHit(hitObject, this);
private class StrongNestedHit : DrawableStrongNestedHit
{
public StrongNestedHit(StrongHitObject strong, DrawableDrumRollTick tick)
: base(strong, tick)
public StrongNestedHit(DrumRollTick.StrongNestedHit nestedHit, DrawableDrumRollTick tick)
: base(nestedHit, tick)
{
}

View File

@ -16,7 +16,7 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableHit : DrawableTaikoHitObject<Hit>
public class DrawableHit : DrawableTaikoStrongableHitObject<Hit, Hit.StrongNestedHit>
{
/// <summary>
/// A list of keys which can result in hits for this HitObject.
@ -228,7 +228,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
protected override DrawableStrongNestedHit CreateStrongHit(StrongHitObject hitObject) => new StrongNestedHit(hitObject, this);
protected override DrawableStrongNestedHit CreateStrongNestedHit(Hit.StrongNestedHit hitObject) => new StrongNestedHit(hitObject, this);
private class StrongNestedHit : DrawableStrongNestedHit
{
@ -240,8 +240,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
public new DrawableHit MainObject => (DrawableHit)base.MainObject;
public StrongNestedHit(StrongHitObject strong, DrawableHit hit)
: base(strong, hit)
public StrongNestedHit(Hit.StrongNestedHit nestedHit, DrawableHit hit)
: base(nestedHit, hit)
{
}

View File

@ -7,14 +7,14 @@ using osu.Game.Rulesets.Taiko.Judgements;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
/// <summary>
/// Used as a nested hitobject to provide <see cref="TaikoStrongJudgement"/>s for <see cref="DrawableTaikoHitObject"/>s.
/// Used as a nested hitobject to provide <see cref="TaikoStrongJudgement"/>s for <see cref="DrawableTaikoStrongableHitObject{TObject,TStrongNestedObject}"/>s.
/// </summary>
public abstract class DrawableStrongNestedHit : DrawableTaikoHitObject
{
public readonly DrawableHitObject MainObject;
protected DrawableStrongNestedHit(StrongHitObject strong, DrawableHitObject mainObject)
: base(strong)
protected DrawableStrongNestedHit(StrongNestedHitObject nestedHit, DrawableHitObject mainObject)
: base(nestedHit)
{
MainObject = mainObject;
}

View File

@ -4,13 +4,11 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Input.Bindings;
using osu.Game.Audio;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Skinning;
using osuTK;
@ -120,112 +118,34 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
protected Vector2 BaseSize;
protected SkinnableDrawable MainPiece;
private readonly Bindable<bool> isStrong;
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
protected DrawableTaikoHitObject(TObject hitObject)
: base(hitObject)
{
HitObject = hitObject;
isStrong = HitObject.IsStrongBindable.GetBoundCopy();
Anchor = Anchor.CentreLeft;
Origin = Anchor.Custom;
RelativeSizeAxes = Axes.Both;
AddInternal(strongHitContainer = new Container<DrawableStrongNestedHit>());
}
[BackgroundDependencyLoader]
private void load()
{
isStrong.BindValueChanged(_ =>
{
// will overwrite samples, should only be called on change.
updateSamplesFromStrong();
RecreatePieces();
});
RecreatePieces();
}
private HitSampleInfo[] getStrongSamples() => HitObject.Samples.Where(s => s.Name == HitSampleInfo.HIT_FINISH).ToArray();
protected override void LoadSamples()
{
base.LoadSamples();
if (HitObject.CanBeStrong)
isStrong.Value = getStrongSamples().Any();
}
private void updateSamplesFromStrong()
{
var strongSamples = getStrongSamples();
if (isStrong.Value != strongSamples.Any())
{
if (isStrong.Value)
HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_FINISH));
else
{
foreach (var sample in strongSamples)
HitObject.Samples.Remove(sample);
}
}
}
protected virtual void RecreatePieces()
{
Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
Size = BaseSize = new Vector2(TaikoHitObject.DEFAULT_SIZE);
MainPiece?.Expire();
Content.Add(MainPiece = CreateMainPiece());
}
protected override void AddNestedHitObject(DrawableHitObject hitObject)
{
base.AddNestedHitObject(hitObject);
switch (hitObject)
{
case DrawableStrongNestedHit strong:
strongHitContainer.Add(strong);
break;
}
}
protected override void ClearNestedHitObjects()
{
base.ClearNestedHitObjects();
strongHitContainer.Clear();
}
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
{
switch (hitObject)
{
case StrongHitObject strong:
return CreateStrongHit(strong);
}
return base.CreateNestedHitObject(hitObject);
}
// Most osu!taiko hitsounds are managed by the drum (see DrumSampleMapping).
public override IEnumerable<HitSampleInfo> GetSamples() => Enumerable.Empty<HitSampleInfo>();
protected abstract SkinnableDrawable CreateMainPiece();
/// <summary>
/// Creates the handler for this <see cref="DrawableHitObject"/>'s <see cref="StrongHitObject"/>.
/// This is only invoked if <see cref="TaikoHitObject.IsStrong"/> is true for <see cref="HitObject"/>.
/// </summary>
/// <param name="hitObject">The strong hitobject.</param>
/// <returns>The strong hitobject handler.</returns>
protected virtual DrawableStrongNestedHit CreateStrongHit(StrongHitObject hitObject) => null;
}
}

View File

@ -0,0 +1,111 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Game.Audio;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public abstract class DrawableTaikoStrongableHitObject<TObject, TStrongNestedObject> : DrawableTaikoHitObject<TObject>
where TObject : TaikoStrongableHitObject
where TStrongNestedObject : StrongNestedHitObject
{
private readonly Bindable<bool> isStrong;
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
protected DrawableTaikoStrongableHitObject(TObject hitObject)
: base(hitObject)
{
isStrong = HitObject.IsStrongBindable.GetBoundCopy();
AddInternal(strongHitContainer = new Container<DrawableStrongNestedHit>());
}
[BackgroundDependencyLoader]
private void load()
{
isStrong.BindValueChanged(_ =>
{
// will overwrite samples, should only be called on change.
updateSamplesFromStrong();
RecreatePieces();
});
}
private HitSampleInfo[] getStrongSamples() => HitObject.Samples.Where(s => s.Name == HitSampleInfo.HIT_FINISH).ToArray();
protected override void LoadSamples()
{
base.LoadSamples();
isStrong.Value = getStrongSamples().Any();
}
private void updateSamplesFromStrong()
{
var strongSamples = getStrongSamples();
if (isStrong.Value != strongSamples.Any())
{
if (isStrong.Value)
HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_FINISH));
else
{
foreach (var sample in strongSamples)
HitObject.Samples.Remove(sample);
}
}
}
protected override void RecreatePieces()
{
base.RecreatePieces();
if (HitObject.IsStrong)
Size = BaseSize = new Vector2(TaikoStrongableHitObject.DEFAULT_STRONG_SIZE);
}
protected override void AddNestedHitObject(DrawableHitObject hitObject)
{
base.AddNestedHitObject(hitObject);
switch (hitObject)
{
case DrawableStrongNestedHit strong:
strongHitContainer.Add(strong);
break;
}
}
protected override void ClearNestedHitObjects()
{
base.ClearNestedHitObjects();
strongHitContainer.Clear();
}
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
{
switch (hitObject)
{
case TStrongNestedObject strong:
return CreateStrongNestedHit(strong);
}
return base.CreateNestedHitObject(hitObject);
}
/// <summary>
/// Creates the handler for this <see cref="DrawableHitObject"/>'s <see cref="StrongNestedHitObject"/>.
/// This is only invoked if <see cref="TaikoStrongableHitObject.IsStrong"/> is true for <see cref="HitObject"/>.
/// </summary>
/// <param name="hitObject">The strong hitobject.</param>
/// <returns>The strong hitobject handler.</returns>
protected abstract DrawableStrongNestedHit CreateStrongNestedHit(TStrongNestedObject hitObject);
}
}

View File

@ -15,7 +15,7 @@ using osuTK;
namespace osu.Game.Rulesets.Taiko.Objects
{
public class DrumRoll : TaikoHitObject, IHasPath
public class DrumRoll : TaikoStrongableHitObject, IHasPath
{
/// <summary>
/// Drum roll distance that results in a duration of 1 speed-adjusted beat length.
@ -109,6 +109,12 @@ namespace osu.Game.Rulesets.Taiko.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime };
public class StrongNestedHit : StrongNestedHitObject
{
}
#region LegacyBeatmapEncoder
double IHasDistance.Distance => Duration * Velocity;

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.Taiko.Judgements;
namespace osu.Game.Rulesets.Taiko.Objects
{
public class DrumRollTick : TaikoHitObject
public class DrumRollTick : TaikoStrongableHitObject
{
/// <summary>
/// Whether this is the first (initial) tick of the slider.
@ -28,5 +28,11 @@ namespace osu.Game.Rulesets.Taiko.Objects
public override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime };
public class StrongNestedHit : StrongNestedHitObject
{
}
}
}

View File

@ -5,7 +5,7 @@ using osu.Framework.Bindables;
namespace osu.Game.Rulesets.Taiko.Objects
{
public class Hit : TaikoHitObject
public class Hit : TaikoStrongableHitObject
{
public readonly Bindable<HitType> TypeBindable = new Bindable<HitType>();
@ -17,5 +17,11 @@ namespace osu.Game.Rulesets.Taiko.Objects
get => TypeBindable.Value;
set => TypeBindable.Value = value;
}
protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime };
public class StrongNestedHit : StrongNestedHitObject
{
}
}
}

View File

@ -7,7 +7,11 @@ using osu.Game.Rulesets.Taiko.Judgements;
namespace osu.Game.Rulesets.Taiko.Objects
{
public class StrongHitObject : TaikoHitObject
/// <summary>
/// Base type for nested strong hits.
/// Used by <see cref="TaikoStrongableHitObject"/>s to represent their strong bonus scoring portions.
/// </summary>
public abstract class StrongNestedHitObject : TaikoHitObject
{
public override Judgement CreateJudgement() => new TaikoStrongJudgement();

View File

@ -17,8 +17,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
set => Duration = value - StartTime;
}
public override bool CanBeStrong => false;
public double Duration { get; set; }
/// <summary>

View File

@ -1,9 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Threading;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
@ -19,47 +16,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
/// </summary>
public const float DEFAULT_SIZE = 0.45f;
/// <summary>
/// Scale multiplier for a strong drawable taiko hit object.
/// </summary>
public const float STRONG_SCALE = 1.4f;
/// <summary>
/// Default size of a strong drawable taiko hit object.
/// </summary>
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
public readonly Bindable<bool> IsStrongBindable = new BindableBool();
/// <summary>
/// Whether this <see cref="TaikoHitObject"/> can be made a "strong" (large) hit.
/// </summary>
public virtual bool CanBeStrong => true;
/// <summary>
/// Whether this HitObject is a "strong" type.
/// Strong hit objects give more points for hitting the hit object with both keys.
/// </summary>
public bool IsStrong
{
get => IsStrongBindable.Value;
set
{
if (value && !CanBeStrong)
throw new InvalidOperationException($"Object of type {GetType()} cannot be strong");
IsStrongBindable.Value = value;
}
}
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
base.CreateNestedHitObjects(cancellationToken);
if (IsStrong)
AddNested(new StrongHitObject { StartTime = this.GetEndTime() });
}
public override Judgement CreateJudgement() => new TaikoJudgement();
protected override HitWindows CreateHitWindows() => new TaikoHitWindows();

View File

@ -0,0 +1,52 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Threading;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Taiko.Objects
{
/// <summary>
/// Base class for taiko hitobjects that can become strong (large).
/// </summary>
public abstract class TaikoStrongableHitObject : TaikoHitObject
{
/// <summary>
/// Scale multiplier for a strong drawable taiko hit object.
/// </summary>
public const float STRONG_SCALE = 1.4f;
/// <summary>
/// Default size of a strong drawable taiko hit object.
/// </summary>
public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE;
public readonly Bindable<bool> IsStrongBindable = new BindableBool();
/// <summary>
/// Whether this HitObject is a "strong" type.
/// Strong hit objects give more points for hitting the hit object with both keys.
/// </summary>
public bool IsStrong
{
get => IsStrongBindable.Value;
set => IsStrongBindable.Value = value;
}
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
base.CreateNestedHitObjects(cancellationToken);
if (IsStrong)
AddNested(CreateStrongNestedHit(this.GetEndTime()));
}
/// <summary>
/// Creates a <see cref="StrongNestedHitObject"/> representing a second hit on this object.
/// This is only called if <see cref="IsStrong"/> is true.
/// </summary>
/// <param name="startTime">The start time of the nested hit.</param>
protected abstract StrongNestedHitObject CreateStrongNestedHit(double startTime);
}
}

View File

@ -102,13 +102,13 @@ namespace osu.Game.Rulesets.Taiko.Replays
if (hit.Type == HitType.Centre)
{
actions = h.IsStrong
actions = hit.IsStrong
? new[] { TaikoAction.LeftCentre, TaikoAction.RightCentre }
: new[] { hitButton ? TaikoAction.LeftCentre : TaikoAction.RightCentre };
}
else
{
actions = h.IsStrong
actions = hit.IsStrong
? new[] { TaikoAction.LeftRim, TaikoAction.RightRim }
: new[] { hitButton ? TaikoAction.LeftRim : TaikoAction.RightRim };
}

View File

@ -7,7 +7,7 @@ using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
const string normal_hit = "taikohit";
const string big_hit = "taikobig";
string prefix = ((drawableHitObject as DrawableTaikoHitObject)?.HitObject.IsStrong ?? false) ? big_hit : normal_hit;
string prefix = ((drawableHitObject.HitObject as TaikoStrongableHitObject)?.IsStrong ?? false) ? big_hit : normal_hit;
return skin.GetAnimation($"{prefix}{lookup}", true, false) ??
// fallback to regular size if "big" version doesn't exist.

View File

@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Taiko.UI
/// </summary>
public void VisualiseSecondHit()
{
this.ResizeTo(new Vector2(TaikoHitObject.DEFAULT_STRONG_SIZE), 50);
this.ResizeTo(new Vector2(TaikoStrongableHitObject.DEFAULT_STRONG_SIZE), 50);
}
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Y,
Size = new Vector2(border_thickness, (1 - TaikoHitObject.DEFAULT_STRONG_SIZE) / 2f),
Size = new Vector2(border_thickness, (1 - TaikoStrongableHitObject.DEFAULT_STRONG_SIZE) / 2f),
Alpha = 0.1f
},
new CircularContainer
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(TaikoHitObject.DEFAULT_STRONG_SIZE),
Size = new Vector2(TaikoStrongableHitObject.DEFAULT_STRONG_SIZE),
Masking = true,
BorderColour = Color4.White,
BorderThickness = border_thickness,
@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Y,
Size = new Vector2(border_thickness, (1 - TaikoHitObject.DEFAULT_STRONG_SIZE) / 2f),
Size = new Vector2(border_thickness, (1 - TaikoStrongableHitObject.DEFAULT_STRONG_SIZE) / 2f),
Alpha = 0.1f
},
};

View File

@ -928,5 +928,6 @@ private void load()
<s:Boolean x:Key="/Default/UserDictionary/Words/=ruleset/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=rulesets/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ruleset_0027s/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Strongable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taiko/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unranked/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>