Beispiel #1
0
 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);
 }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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();
                }
            }
        }
Beispiel #4
0
        public void OnRevertResult(DrawableCatchHitObject judgedObject, JudgementResult result)
        {
            if (!result.Type.AffectsCombo() || !result.HasResult)
            {
                return;
            }

            updateCombo(result.ComboAtJudgement, judgedObject.AccentColour.Value);
        }
Beispiel #5
0
        private void addToPlayfield(DrawableCatchHitObject drawable)
        {
            foreach (var mod in SelectedMods.Value.OfType <IApplicableToDrawableHitObjects>())
            {
                mod.ApplyToDrawableHitObjects(new[] { drawable });
            }

            drawableRuleset.Playfield.Add(drawable);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 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();
     };
 }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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();
                }
            }
        }
Beispiel #12
0
        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());
            }
        }
Beispiel #13
0
        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();
                }
            }
Beispiel #14
0
        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);
            }
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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,
                },
            };
        }
Beispiel #18
0
        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);
        }
Beispiel #22
0
        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,
                    },
                }
            };
        }