mirror of
https://github.com/ppy/osu.git
synced 2025-03-28 09:37:23 +08:00
Merge branch 'master' into mod-settings-dropdown-height
This commit is contained in:
commit
cb6fbd88c7
14
osu.Game.Rulesets.Catch.Tests/Editor/TestSceneEditor.cs
Normal file
14
osu.Game.Rulesets.Catch.Tests/Editor/TestSceneEditor.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// 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 NUnit.Framework;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Tests.Editor
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneEditor : EditorTestScene
|
||||||
|
{
|
||||||
|
protected override Ruleset CreateEditorRuleset() => new CatchRuleset();
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,9 @@ using osu.Game.Rulesets.Scoring;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Extensions.EnumExtensions;
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
|
using osu.Game.Rulesets.Catch.Edit;
|
||||||
using osu.Game.Rulesets.Catch.Skinning.Legacy;
|
using osu.Game.Rulesets.Catch.Skinning.Legacy;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch
|
namespace osu.Game.Rulesets.Catch
|
||||||
@ -182,5 +184,7 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
public int LegacyID => 2;
|
public int LegacyID => 2;
|
||||||
|
|
||||||
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
|
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
|
||||||
|
|
||||||
|
public override HitObjectComposer CreateHitObjectComposer() => new CatchHitObjectComposer(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs
Normal file
24
osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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 osu.Framework.Graphics;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class BananaShowerCompositionTool : HitObjectCompositionTool
|
||||||
|
{
|
||||||
|
public BananaShowerCompositionTool()
|
||||||
|
: base(nameof(BananaShower))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Spinners);
|
||||||
|
|
||||||
|
public override PlacementBlueprint CreatePlacementBlueprint() => new BananaShowerPlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
// 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 osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Rulesets.Catch.Edit.Blueprints.Components;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class BananaShowerPlacementBlueprint : CatchPlacementBlueprint<BananaShower>
|
||||||
|
{
|
||||||
|
private readonly TimeSpanOutline outline;
|
||||||
|
|
||||||
|
public BananaShowerPlacementBlueprint()
|
||||||
|
{
|
||||||
|
InternalChild = outline = new TimeSpanOutline();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
outline.UpdateFrom(HitObjectContainer, HitObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
|
{
|
||||||
|
switch (PlacementActive)
|
||||||
|
{
|
||||||
|
case PlacementState.Waiting:
|
||||||
|
if (e.Button != MouseButton.Left) break;
|
||||||
|
|
||||||
|
BeginPlacement(true);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case PlacementState.Active:
|
||||||
|
if (e.Button != MouseButton.Right) break;
|
||||||
|
|
||||||
|
// If the duration is negative, swap the start and the end time to make the duration positive.
|
||||||
|
if (HitObject.Duration < 0)
|
||||||
|
{
|
||||||
|
HitObject.StartTime = HitObject.EndTime;
|
||||||
|
HitObject.Duration = -HitObject.Duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndPlacement(HitObject.Duration > 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnMouseDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateTimeAndPosition(SnapResult result)
|
||||||
|
{
|
||||||
|
base.UpdateTimeAndPosition(result);
|
||||||
|
|
||||||
|
if (!(result.Time is double time)) return;
|
||||||
|
|
||||||
|
switch (PlacementActive)
|
||||||
|
{
|
||||||
|
case PlacementState.Waiting:
|
||||||
|
HitObject.StartTime = time;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlacementState.Active:
|
||||||
|
HitObject.EndTime = time;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
// 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 osu.Game.Rulesets.Catch.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class BananaShowerSelectionBlueprint : CatchSelectionBlueprint<BananaShower>
|
||||||
|
{
|
||||||
|
public BananaShowerSelectionBlueprint(BananaShower hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class CatchPlacementBlueprint<THitObject> : PlacementBlueprint
|
||||||
|
where THitObject : CatchHitObject, new()
|
||||||
|
{
|
||||||
|
protected new THitObject HitObject => (THitObject)base.HitObject;
|
||||||
|
|
||||||
|
protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private Playfield playfield { get; set; }
|
||||||
|
|
||||||
|
public CatchPlacementBlueprint()
|
||||||
|
: base(new THitObject())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public abstract class CatchSelectionBlueprint<THitObject> : HitObjectSelectionBlueprint<THitObject>
|
||||||
|
where THitObject : CatchHitObject
|
||||||
|
{
|
||||||
|
public override Vector2 ScreenSpaceSelectionPoint
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
float x = HitObject.OriginalX;
|
||||||
|
float y = HitObjectContainer.PositionAtTime(HitObject.StartTime);
|
||||||
|
return HitObjectContainer.ToScreenSpace(new Vector2(x, y + HitObjectContainer.DrawHeight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => SelectionQuad.Contains(screenSpacePos);
|
||||||
|
|
||||||
|
protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private Playfield playfield { get; set; }
|
||||||
|
|
||||||
|
protected CatchSelectionBlueprint(THitObject hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Catch.Skinning.Default;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
|
||||||
|
{
|
||||||
|
public class FruitOutline : CompositeDrawable
|
||||||
|
{
|
||||||
|
public FruitOutline()
|
||||||
|
{
|
||||||
|
Anchor = Anchor.BottomLeft;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
Size = new Vector2(2 * CatchHitObject.OBJECT_RADIUS);
|
||||||
|
InternalChild = new BorderPiece();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour osuColour)
|
||||||
|
{
|
||||||
|
Colour = osuColour.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateFrom(ScrollingHitObjectContainer hitObjectContainer, CatchHitObject hitObject)
|
||||||
|
{
|
||||||
|
X = hitObject.EffectiveX;
|
||||||
|
Y = hitObjectContainer.PositionAtTime(hitObject.StartTime);
|
||||||
|
Scale = new Vector2(hitObject.Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
|
||||||
|
{
|
||||||
|
public class TimeSpanOutline : CompositeDrawable
|
||||||
|
{
|
||||||
|
private const float border_width = 4;
|
||||||
|
|
||||||
|
private const float opacity_when_empty = 0.5f;
|
||||||
|
|
||||||
|
private bool isEmpty = true;
|
||||||
|
|
||||||
|
public TimeSpanOutline()
|
||||||
|
{
|
||||||
|
Anchor = Origin = Anchor.BottomLeft;
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
BorderThickness = border_width;
|
||||||
|
Alpha = opacity_when_empty;
|
||||||
|
|
||||||
|
// A box is needed to make the border visible.
|
||||||
|
InternalChild = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Transparent
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour osuColour)
|
||||||
|
{
|
||||||
|
BorderColour = osuColour.Yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateFrom(ScrollingHitObjectContainer hitObjectContainer, BananaShower hitObject)
|
||||||
|
{
|
||||||
|
float startY = hitObjectContainer.PositionAtTime(hitObject.StartTime);
|
||||||
|
float endY = hitObjectContainer.PositionAtTime(hitObject.EndTime);
|
||||||
|
|
||||||
|
Y = Math.Max(startY, endY);
|
||||||
|
float height = Math.Abs(startY - endY);
|
||||||
|
|
||||||
|
bool wasEmpty = isEmpty;
|
||||||
|
isEmpty = height == 0;
|
||||||
|
if (wasEmpty != isEmpty)
|
||||||
|
this.FadeTo(isEmpty ? opacity_when_empty : 1f, 150);
|
||||||
|
|
||||||
|
Height = Math.Max(height, border_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
// 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 osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Rulesets.Catch.Edit.Blueprints.Components;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class FruitPlacementBlueprint : CatchPlacementBlueprint<Fruit>
|
||||||
|
{
|
||||||
|
private readonly FruitOutline outline;
|
||||||
|
|
||||||
|
public FruitPlacementBlueprint()
|
||||||
|
{
|
||||||
|
InternalChild = outline = new FruitOutline();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
BeginPlacement();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
outline.UpdateFrom(HitObjectContainer, HitObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
|
{
|
||||||
|
if (e.Button != MouseButton.Left) return base.OnMouseDown(e);
|
||||||
|
|
||||||
|
EndPlacement(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateTimeAndPosition(SnapResult result)
|
||||||
|
{
|
||||||
|
base.UpdateTimeAndPosition(result);
|
||||||
|
|
||||||
|
HitObject.X = ToLocalSpace(result.ScreenSpacePosition).X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
// 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 osu.Game.Rulesets.Catch.Edit.Blueprints.Components;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class FruitSelectionBlueprint : CatchSelectionBlueprint<Fruit>
|
||||||
|
{
|
||||||
|
private readonly FruitOutline outline;
|
||||||
|
|
||||||
|
public FruitSelectionBlueprint(Fruit hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
InternalChild = outline = new FruitOutline();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (IsSelected)
|
||||||
|
outline.UpdateFrom(HitObjectContainer, HitObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
// 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.Graphics.Primitives;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
|
{
|
||||||
|
public class JuiceStreamSelectionBlueprint : CatchSelectionBlueprint<JuiceStream>
|
||||||
|
{
|
||||||
|
public override Quad SelectionQuad => HitObjectContainer.ToScreenSpace(getBoundingBox().Offset(new Vector2(0, HitObjectContainer.DrawHeight)));
|
||||||
|
|
||||||
|
private float minNestedX;
|
||||||
|
private float maxNestedX;
|
||||||
|
|
||||||
|
public JuiceStreamSelectionBlueprint(JuiceStream hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
HitObject.DefaultsApplied += onDefaultsApplied;
|
||||||
|
computeObjectBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDefaultsApplied(HitObject _) => computeObjectBounds();
|
||||||
|
|
||||||
|
private void computeObjectBounds()
|
||||||
|
{
|
||||||
|
minNestedX = HitObject.NestedHitObjects.OfType<CatchHitObject>().Min(nested => nested.OriginalX) - HitObject.OriginalX;
|
||||||
|
maxNestedX = HitObject.NestedHitObjects.OfType<CatchHitObject>().Max(nested => nested.OriginalX) - HitObject.OriginalX;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RectangleF getBoundingBox()
|
||||||
|
{
|
||||||
|
float left = HitObject.OriginalX + minNestedX;
|
||||||
|
float right = HitObject.OriginalX + maxNestedX;
|
||||||
|
float top = HitObjectContainer.PositionAtTime(HitObject.EndTime);
|
||||||
|
float bottom = HitObjectContainer.PositionAtTime(HitObject.StartTime);
|
||||||
|
float objectRadius = CatchHitObject.OBJECT_RADIUS * HitObject.Scale;
|
||||||
|
return new RectangleF(left, top, right - left, bottom - top).Inflate(objectRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
HitObject.DefaultsApplied -= onDefaultsApplied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs
Normal file
38
osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// 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 osu.Game.Rulesets.Catch.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class CatchBlueprintContainer : ComposeBlueprintContainer
|
||||||
|
{
|
||||||
|
public CatchBlueprintContainer(CatchHitObjectComposer composer)
|
||||||
|
: base(composer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SelectionHandler<HitObject> CreateSelectionHandler() => new CatchSelectionHandler();
|
||||||
|
|
||||||
|
public override HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case Fruit fruit:
|
||||||
|
return new FruitSelectionBlueprint(fruit);
|
||||||
|
|
||||||
|
case JuiceStream juiceStream:
|
||||||
|
return new JuiceStreamSelectionBlueprint(juiceStream);
|
||||||
|
|
||||||
|
case BananaShower bananaShower:
|
||||||
|
return new BananaShowerSelectionBlueprint(bananaShower);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateHitObjectBlueprintFor(hitObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs
Normal file
27
osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// 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 osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class CatchEditorPlayfield : CatchPlayfield
|
||||||
|
{
|
||||||
|
// TODO fixme: the size of the catcher is not changed when circle size is changed in setup screen.
|
||||||
|
public CatchEditorPlayfield(BeatmapDifficulty difficulty)
|
||||||
|
: base(difficulty)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
// TODO: honor "hit animation" setting?
|
||||||
|
CatcherArea.MovableCatcher.CatchFruitOnPlate = false;
|
||||||
|
|
||||||
|
// TODO: disable hit lighting as well
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs
Normal file
42
osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class CatchHitObjectComposer : HitObjectComposer<CatchHitObject>
|
||||||
|
{
|
||||||
|
public CatchHitObjectComposer(CatchRuleset ruleset)
|
||||||
|
: base(ruleset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableRuleset<CatchHitObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null) =>
|
||||||
|
new DrawableCatchEditorRuleset(ruleset, beatmap, mods);
|
||||||
|
|
||||||
|
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||||
|
{
|
||||||
|
new FruitCompositionTool(),
|
||||||
|
new BananaShowerCompositionTool()
|
||||||
|
};
|
||||||
|
|
||||||
|
public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition)
|
||||||
|
{
|
||||||
|
var result = base.SnapScreenSpacePositionToValidTime(screenSpacePosition);
|
||||||
|
// TODO: implement position snap
|
||||||
|
result.ScreenSpacePosition.X = screenSpacePosition.X;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this);
|
||||||
|
}
|
||||||
|
}
|
46
osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs
Normal file
46
osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// 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.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class CatchSelectionHandler : EditorSelectionHandler
|
||||||
|
{
|
||||||
|
protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private Playfield playfield { get; set; }
|
||||||
|
|
||||||
|
public override bool HandleMovement(MoveSelectionEvent<HitObject> moveEvent)
|
||||||
|
{
|
||||||
|
var blueprint = moveEvent.Blueprint;
|
||||||
|
Vector2 originalPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint);
|
||||||
|
Vector2 targetPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint + moveEvent.ScreenSpaceDelta);
|
||||||
|
float deltaX = targetPosition.X - originalPosition.X;
|
||||||
|
|
||||||
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
|
{
|
||||||
|
if (!(h is CatchHitObject hitObject)) return;
|
||||||
|
|
||||||
|
if (hitObject is BananaShower) return;
|
||||||
|
|
||||||
|
// TODO: confine in bounds
|
||||||
|
hitObject.OriginalXBindable.Value += deltaX;
|
||||||
|
|
||||||
|
// Move the nested hit objects to give an instant result before nested objects are recreated.
|
||||||
|
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>())
|
||||||
|
nested.OriginalXBindable.Value += deltaX;
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs
Normal file
21
osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class DrawableCatchEditorRuleset : DrawableCatchRuleset
|
||||||
|
{
|
||||||
|
public DrawableCatchEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
||||||
|
: base(ruleset, beatmap, mods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Playfield CreatePlayfield() => new CatchEditorPlayfield(Beatmap.BeatmapInfo.BaseDifficulty);
|
||||||
|
}
|
||||||
|
}
|
24
osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs
Normal file
24
osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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 osu.Framework.Graphics;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
public class FruitCompositionTool : HitObjectCompositionTool
|
||||||
|
{
|
||||||
|
public FruitCompositionTool()
|
||||||
|
: base(nameof(Fruit))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Drawable CreateIcon() => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Circles);
|
||||||
|
|
||||||
|
public override PlacementBlueprint CreatePlacementBlueprint() => new FruitPlacementBlueprint();
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game/Rulesets/Mods/IHasSeed.cs
Normal file
12
osu.Game/Rulesets/Mods/IHasSeed.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// 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 osu.Framework.Bindables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
public interface IHasSeed
|
||||||
|
{
|
||||||
|
Bindable<int?> Seed { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -2,17 +2,13 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Overlays.Settings;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
public abstract class ModRandom : Mod
|
public abstract class ModRandom : Mod, IHasSeed
|
||||||
{
|
{
|
||||||
public override string Name => "Random";
|
public override string Name => "Random";
|
||||||
public override string Acronym => "RD";
|
public override string Acronym => "RD";
|
||||||
@ -20,88 +16,11 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override IconUsage? Icon => OsuIcon.Dice;
|
public override IconUsage? Icon => OsuIcon.Dice;
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(ModRandomSettingsControl))]
|
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SeedSettingsControl))]
|
||||||
public Bindable<int?> Seed { get; } = new Bindable<int?>
|
public Bindable<int?> Seed { get; } = new Bindable<int?>
|
||||||
{
|
{
|
||||||
Default = null,
|
Default = null,
|
||||||
Value = null
|
Value = null
|
||||||
};
|
};
|
||||||
|
|
||||||
private class ModRandomSettingsControl : SettingsItem<int?>
|
|
||||||
{
|
|
||||||
protected override Drawable CreateControl() => new SeedControl
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Margin = new MarginPadding { Top = 5 }
|
|
||||||
};
|
|
||||||
|
|
||||||
private sealed class SeedControl : CompositeDrawable, IHasCurrentValue<int?>
|
|
||||||
{
|
|
||||||
private readonly BindableWithCurrent<int?> current = new BindableWithCurrent<int?>();
|
|
||||||
|
|
||||||
public Bindable<int?> Current
|
|
||||||
{
|
|
||||||
get => current;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
current.Current = value;
|
|
||||||
seedNumberBox.Text = value.Value.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly SettingsNumberBox.NumberBox seedNumberBox;
|
|
||||||
|
|
||||||
public SeedControl()
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Y;
|
|
||||||
|
|
||||||
InternalChildren = new[]
|
|
||||||
{
|
|
||||||
new GridContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
ColumnDimensions = new[]
|
|
||||||
{
|
|
||||||
new Dimension(),
|
|
||||||
new Dimension(GridSizeMode.Absolute, 2),
|
|
||||||
new Dimension(GridSizeMode.Relative, 0.25f)
|
|
||||||
},
|
|
||||||
RowDimensions = new[]
|
|
||||||
{
|
|
||||||
new Dimension(GridSizeMode.AutoSize)
|
|
||||||
},
|
|
||||||
Content = new[]
|
|
||||||
{
|
|
||||||
new Drawable[]
|
|
||||||
{
|
|
||||||
seedNumberBox = new SettingsNumberBox.NumberBox
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
CommitOnFocusLost = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
seedNumberBox.Current.BindValueChanged(e =>
|
|
||||||
{
|
|
||||||
int? value = null;
|
|
||||||
|
|
||||||
if (int.TryParse(e.NewValue, out var intVal))
|
|
||||||
value = intVal;
|
|
||||||
|
|
||||||
current.Value = value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
if (current.Value == null)
|
|
||||||
seedNumberBox.Text = current.Current.Value.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
92
osu.Game/Rulesets/Mods/SeedSettingsControl.cs
Normal file
92
osu.Game/Rulesets/Mods/SeedSettingsControl.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// 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 osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A settings control for use by <see cref="IHasSeed"/> mods which have a customisable seed value.
|
||||||
|
/// </summary>
|
||||||
|
public class SeedSettingsControl : SettingsItem<int?>
|
||||||
|
{
|
||||||
|
protected override Drawable CreateControl() => new SeedControl
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Margin = new MarginPadding { Top = 5 }
|
||||||
|
};
|
||||||
|
|
||||||
|
private sealed class SeedControl : CompositeDrawable, IHasCurrentValue<int?>
|
||||||
|
{
|
||||||
|
private readonly BindableWithCurrent<int?> current = new BindableWithCurrent<int?>();
|
||||||
|
|
||||||
|
public Bindable<int?> Current
|
||||||
|
{
|
||||||
|
get => current;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
current.Current = value;
|
||||||
|
seedNumberBox.Text = value.Value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly OsuNumberBox seedNumberBox;
|
||||||
|
|
||||||
|
public SeedControl()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
InternalChildren = new[]
|
||||||
|
{
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
ColumnDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(),
|
||||||
|
new Dimension(GridSizeMode.Absolute, 2),
|
||||||
|
new Dimension(GridSizeMode.Relative, 0.25f)
|
||||||
|
},
|
||||||
|
RowDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize)
|
||||||
|
},
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
seedNumberBox = new OsuNumberBox
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
CommitOnFocusLost = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
seedNumberBox.Current.BindValueChanged(e =>
|
||||||
|
{
|
||||||
|
int? value = null;
|
||||||
|
|
||||||
|
if (int.TryParse(e.NewValue, out var intVal))
|
||||||
|
value = intVal;
|
||||||
|
|
||||||
|
current.Value = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
if (current.Value == null)
|
||||||
|
seedNumberBox.Text = current.Current.Value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -94,6 +95,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// Creates a <see cref="SelectionBlueprint{T}"/> for a specific item.
|
/// Creates a <see cref="SelectionBlueprint{T}"/> for a specific item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item to create the overlay for.</param>
|
/// <param name="item">The item to create the overlay for.</param>
|
||||||
|
[CanBeNull]
|
||||||
protected virtual SelectionBlueprint<T> CreateBlueprintFor(T item) => null;
|
protected virtual SelectionBlueprint<T> CreateBlueprintFor(T item) => null;
|
||||||
|
|
||||||
protected virtual DragBox CreateDragBox(Action<RectangleF> performSelect) => new DragBox(performSelect);
|
protected virtual DragBox CreateDragBox(Action<RectangleF> performSelect) => new DragBox(performSelect);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -256,9 +257,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
if (drawable == null)
|
if (drawable == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return CreateHitObjectBlueprintFor(item).With(b => b.DrawableObject = drawable);
|
return CreateHitObjectBlueprintFor(item)?.With(b => b.DrawableObject = drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
public virtual HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject) => null;
|
public virtual HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject) => null;
|
||||||
|
|
||||||
private void hitObjectAdded(HitObject obj)
|
private void hitObjectAdded(HitObject obj)
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -89,7 +90,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
placementBlueprint = CreateBlueprintFor(obj.NewValue);
|
placementBlueprint = CreateBlueprintFor(obj.NewValue).AsNonNull();
|
||||||
|
|
||||||
placementBlueprint.Colour = Color4.MediumPurple;
|
placementBlueprint.Colour = Color4.MediumPurple;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user