private void attemptCatch(CatchHitObject hitObject, out DrawableCatchHitObject drawableObject, out JudgementResult result) { hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); drawableObject = createDrawableObject(hitObject); result = createResult(hitObject); applyResult(drawableObject, result); }
public void TestCatcherHyperStateReverted() { DrawableCatchHitObject drawableObject1 = null; DrawableCatchHitObject drawableObject2 = null; JudgementResult result1 = null; JudgementResult result2 = null; AddStep("catch hyper fruit", () => { attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } }, out drawableObject1, out result1); }); AddStep("catch normal fruit", () => { attemptCatch(new Fruit(), out drawableObject2, out result2); }); AddStep("revert second result", () => { catcher.OnRevertResult(drawableObject2, result2); }); checkHyperDash(true); AddStep("revert first result", () => { catcher.OnRevertResult(drawableObject1, result1); }); checkHyperDash(false); }
public void OnResult(DrawableCatchHitObject fruit, JudgementResult result) { void runAfterLoaded(Action action) { if (lastPlateableFruit == null) { return; } // this is required to make this run after the last caught fruit runs UpdateState at least once. // TODO: find a better alternative if (lastPlateableFruit.IsLoaded) { action(); } else { lastPlateableFruit.OnLoadComplete = _ => action(); } } if (result.IsHit && fruit.CanBePlated) { var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject); if (caughtFruit == null) { return; } caughtFruit.RelativePositionAxes = Axes.None; caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); caughtFruit.Anchor = Anchor.TopCentre; caughtFruit.Origin = Anchor.Centre; caughtFruit.Scale *= 0.7f; caughtFruit.LifetimeEnd = double.MaxValue; MovableCatcher.Add(caughtFruit); lastPlateableFruit = caughtFruit; if (!fruit.StaysOnPlate) { runAfterLoaded(() => MovableCatcher.Explode(caughtFruit)); } } if (fruit.HitObject.LastInCombo) { if (((CatchJudgement)result.Judgement).ShouldExplodeFor(result)) { runAfterLoaded(() => MovableCatcher.Explode()); } else { MovableCatcher.Drop(); } } }
public void OnRevertResult(DrawableCatchHitObject judgedObject, JudgementResult result) { if (!result.Type.AffectsCombo() || !result.HasResult) { return; } updateCombo(result.ComboAtJudgement, judgedObject.AccentColour.Value); }
private void addToPlayfield(DrawableCatchHitObject drawable) { foreach (var mod in SelectedMods.Value.OfType <IApplicableToDrawableHitObjects>()) { mod.ApplyToDrawableHitObjects(new[] { drawable }); } drawableRuleset.Playfield.Add(drawable); }
private void fadeOutHitObject(DrawableCatchHitObject drawable) { var hitObject = drawable.HitObject; double offset = hitObject.TimePreempt * fade_out_offset_multiplier; double duration = offset - hitObject.TimePreempt * fade_out_duration_multiplier; using (drawable.BeginAbsoluteSequence(hitObject.StartTime - offset)) drawable.FadeOut(duration); }
private void applyResult(DrawableCatchHitObject drawableObject, JudgementResult result) { // Load DHO to set colour of hit explosion correctly Add(drawableObject); drawableObject.OnLoadComplete += _ => { catcher.OnNewResult(drawableObject, result); drawableObject.Expire(); }; }
private JudgementResult attemptCatch(DrawableCatchHitObject drawableObject) { drawableObject.HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); var result = new CatchJudgementResult(drawableObject.HitObject, drawableObject.HitObject.CreateJudgement()) { Type = catcher.CanCatch(drawableObject.HitObject) ? HitResult.Great : HitResult.Miss }; catcher.OnNewResult(drawableObject, result); return(result); }
public void OnNewResult(DrawableCatchHitObject judgedObject, JudgementResult result) { if (!result.Type.AffectsCombo() || !result.HasResult) { return; } if (!result.IsHit) { updateCombo(0, null); return; } updateCombo(result.ComboAtJudgement + 1, judgedObject.AccentColour.Value); }
public void TestCatcherAnimationStateReverted() { DrawableCatchHitObject drawableObject = null; JudgementResult result = null; AddStep("catch kiai fruit", () => { attemptCatch(new TestKiaiFruit(), out drawableObject, out result); }); checkState(CatcherAnimationState.Kiai); AddStep("revert result", () => { catcher.OnRevertResult(drawableObject, result); }); checkState(CatcherAnimationState.Idle); }
public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement) { if (judgement.IsHit && fruit.CanBePlated) { var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject); if (caughtFruit == null) { return; } caughtFruit.AccentColour = fruit.AccentColour; caughtFruit.RelativePositionAxes = Axes.None; caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); caughtFruit.Anchor = Anchor.TopCentre; caughtFruit.Origin = Anchor.Centre; caughtFruit.Scale *= 0.7f; caughtFruit.LifetimeEnd = double.MaxValue; MovableCatcher.Add(caughtFruit); lastPlateableFruit = caughtFruit; } if (fruit.HitObject.LastInCombo) { if (judgement.IsHit) { // this is required to make this run after the last caught fruit runs UpdateState at least once. // TODO: find a better alternative if (lastPlateableFruit.IsLoaded) { MovableCatcher.Explode(); } else { lastPlateableFruit.OnLoadComplete = _ => { MovableCatcher.Explode(); } }; } else { MovableCatcher.Drop(); } } }
private void load([CanBeNull] DrawableHitObject drawable) { drawableHitObject = (DrawableCatchHitObject)drawable; AddInternal(getFruitFor(VisualRepresentation.Value)); // if it is not part of a DHO, the border is always invisible. if (drawableHitObject != null) { AddInternal(borderPiece = new BorderPiece()); } if (HyperDash.Value) { AddInternal(new HyperBorderPiece()); } }
public void OnNewResult(DrawableCatchHitObject hitObject, JudgementResult result) { if (!result.Type.IsScorable()) { return; } if (hitObject.HitObject.LastInCombo) { if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result)) { MovableCatcher.Explode(); } else { MovableCatcher.Drop(); } }
private void load(DrawableHitObject drawableObject, ISkinSource skin) { DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; accentColour.BindTo(drawableCatchObject.AccentColour); InternalChildren = new Drawable[] { colouredSprite = new Sprite { Texture = skin.GetTexture(lookupName), Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, new Sprite { Texture = skin.GetTexture($"{lookupName}-overlay"), Anchor = Anchor.Centre, Origin = Anchor.Centre, }, }; if (drawableCatchObject.HitObject.HyperDash) { var hyperDash = new Sprite { Anchor = Anchor.Centre, Origin = Anchor.Centre, Blending = BlendingParameters.Additive, Depth = 1, Alpha = 0.7f, Scale = new Vector2(1.2f), Texture = skin.GetTexture(lookupName), Colour = skin.GetConfig <CatchSkinColour, Color4>(CatchSkinColour.HyperDashFruit)?.Value ?? skin.GetConfig <CatchSkinColour, Color4>(CatchSkinColour.HyperDash)?.Value ?? Catcher.DEFAULT_HYPER_DASH_COLOUR, }; AddInternal(hyperDash); } }
protected virtual DrawableCatchHitObject SetProperties(DrawableCatchHitObject d) { var hitObject = d.HitObject; hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 0 }); hitObject.StartTime = 1000000000000; hitObject.Scale = 1.5f; d.Anchor = Anchor.Centre; d.RelativePositionAxes = Axes.None; d.Position = Vector2.Zero; d.HitObjectApplied += _ => { d.LifetimeStart = double.NegativeInfinity; d.LifetimeEnd = double.PositiveInfinity; }; return(d); }
private DrawableCatchHitObject setProperties(DrawableCatchHitObject d, bool hyperdash = false) { var hitObject = d.HitObject; hitObject.StartTime = 1000000000000; hitObject.Scale = 1.5f; if (hyperdash) { hitObject.HyperDashTarget = new Banana(); } d.Anchor = Anchor.Centre; d.RelativePositionAxes = Axes.None; d.Position = Vector2.Zero; d.HitObjectApplied += _ => { d.LifetimeStart = double.NegativeInfinity; d.LifetimeEnd = double.PositiveInfinity; }; return(d); }
private void load(DrawableHitObject drawableObject, ISkinSource skin) { DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; accentColour.BindTo(drawableCatchObject.AccentColour); InternalChildren = new Drawable[] { colouredSprite = new Sprite { Texture = skin.GetTexture(lookupName), Colour = drawableObject.AccentColour.Value, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, new Sprite { Texture = skin.GetTexture($"{lookupName}-overlay"), Anchor = Anchor.Centre, Origin = Anchor.Centre, }, }; }
public TestDrawableCatchHitObjectSpecimen(DrawableCatchHitObject d) { AutoSizeAxes = Axes.Both; Anchor = Anchor.Centre; Origin = Anchor.Centre; ManualClock = new ManualClock(); Clock = new FramedClock(ManualClock); var hitObject = d.HitObject; hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); hitObject.Scale = 1.5f; hitObject.StartTime = 500; d.Anchor = Anchor.Centre; d.HitObjectApplied += _ => { d.LifetimeStart = double.NegativeInfinity; d.LifetimeEnd = double.PositiveInfinity; }; InternalChild = d; }
protected override void AddHitObject(DrawableHitObject hitObject) { LastObject = (DrawableCatchHitObject)hitObject; contentContainer.Playfield.HitObjectContainer.Add(hitObject); }
public void Setup() => Schedule(() => { HitObjectContainer.Clear(); ResetPlacement(); LastObject = null; });
private void load(DrawableHitObject drawableObject) { DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; AccentColour.BindTo(drawableCatchObject.AccentColour); }
public HitExplosion(DrawableCatchHitObject fruit) { Size = new Vector2(20); Anchor = Anchor.TopCentre; Origin = Anchor.BottomCentre; Color4 objectColour = fruit.AccentColour.Value; // scale roughly in-line with visual appearance of notes const float angle_variangle = 15; // should be less than 45 const float roundness = 100; const float initial_height = 10; var colour = Interpolation.ValueAt(0.4f, objectColour, Color4.White, 0, 1); InternalChildren = new Drawable[] { largeFaint = new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, // we want our size to be very small so the glow dominates it. Size = new Vector2(0.8f), Blending = BlendingParameters.Additive, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = Interpolation.ValueAt(0.1f, objectColour, Color4.White, 0, 1).Opacity(0.3f), Roundness = 160, Radius = 200, }, }, new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, Blending = BlendingParameters.Additive, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = Interpolation.ValueAt(0.6f, objectColour, Color4.White, 0, 1), Roundness = 20, Radius = 50, }, }, new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, Size = new Vector2(0.01f, initial_height), Blending = BlendingParameters.Additive, Rotation = RNG.NextSingle(-angle_variangle, angle_variangle), EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = colour, Roundness = roundness, Radius = 40, }, }, new CircularContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, Size = new Vector2(0.01f, initial_height), Blending = BlendingParameters.Additive, Rotation = RNG.NextSingle(-angle_variangle, angle_variangle), EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = colour, Roundness = roundness, Radius = 40, }, } }; }