public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; DrawableHitCircle c = h as DrawableHitCircle; if (c != null) { approachCircles.Add(c.ApproachCircle.CreateProxy()); } h.OnJudgement += judgement; base.Add(h); }
protected override void AddHitObject(DrawableHitObject hitObject) { LastObject = (DrawableCatchHitObject)hitObject; contentContainer.Playfield.HitObjectContainer.Add(hitObject); }
public override void Add(DrawableHitObject h) { Columns[((StraightHitObject)h.HitObject).Column].Add(h); Columns[((StraightHitObject)h.HitObject).Column].AddChild(h); }
public override void Add(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Add(h);
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { base.ApplyIncreasedVisibilityState(hitObject, state); applyState(hitObject, true); }
private void applyState(DrawableHitObject drawable, bool increaseVisibility) { if (!(drawable is DrawableOsuHitObject d)) { return; } var h = d.HitObject; var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadeIn; var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier; // new duration from completed fade in to end (before fading out) var longFadeDuration = h.GetEndTime() - fadeOutStartTime; switch (drawable) { case DrawableSliderTail sliderTail: // use stored values from head circle to achieve same fade sequence. var tailFadeOutParameters = getFadeOutParametersFromSliderHead(h); using (drawable.BeginAbsoluteSequence(tailFadeOutParameters.startTime, true)) sliderTail.FadeOut(tailFadeOutParameters.duration); break; case DrawableSliderRepeat sliderRepeat: // use stored values from head circle to achieve same fade sequence. var repeatFadeOutParameters = getFadeOutParametersFromSliderHead(h); using (drawable.BeginAbsoluteSequence(repeatFadeOutParameters.startTime, true)) // only apply to circle piece – reverse arrow is not affected by hidden. sliderRepeat.CirclePiece.FadeOut(repeatFadeOutParameters.duration); break; case DrawableHitCircle circle: Drawable fadeTarget = circle; if (increaseVisibility) { // only fade the circle piece (not the approach circle) for the increased visibility object. fadeTarget = circle.CirclePiece; } else { // we don't want to see the approach circle using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt, true)) circle.ApproachCircle.Hide(); } // fade out immediately after fade in. using (drawable.BeginAbsoluteSequence(fadeOutStartTime, true)) fadeTarget.FadeOut(fadeOutDuration); break; case DrawableSlider slider: associateNestedSliderCirclesWithHead(slider.HitObject); using (slider.BeginAbsoluteSequence(fadeOutStartTime, true)) slider.Body.FadeOut(longFadeDuration, Easing.Out); break; case DrawableSliderTick sliderTick: // slider ticks fade out over up to one second var tickFadeOutDuration = Math.Min(sliderTick.HitObject.TimePreempt - DrawableSliderTick.ANIM_DURATION, 1000); using (sliderTick.BeginAbsoluteSequence(sliderTick.HitObject.StartTime - tickFadeOutDuration, true)) sliderTick.FadeOut(tickFadeOutDuration); break; case DrawableSpinner spinner: // hide elements we don't care about. // todo: hide background using (spinner.BeginAbsoluteSequence(fadeOutStartTime + longFadeDuration, true)) spinner.FadeOut(fadeOutDuration); break; } }
DrawableHitObject IPooledHitObjectProvider.GetPooledDrawableRepresentation(HitObject hitObject, DrawableHitObject parent) { var lookupType = hitObject.GetType(); IDrawablePool pool; // Tests may add derived hitobject instances for which pools don't exist. Try to find any applicable pool and dynamically assign the type if the pool exists. if (!pools.TryGetValue(lookupType, out pool)) { foreach (var(t, p) in pools) { if (!t.IsInstanceOfType(hitObject)) { continue; } pools[lookupType] = pool = p; break; } } return((DrawableHitObject)pool?.Get(d => { var dho = (DrawableHitObject)d; if (!dho.IsInitialized) { onNewDrawableHitObject(dho); // If this is the first time this DHO is being used, then apply the DHO mods. // This is done before Apply() so that the state is updated once when the hitobject is applied. foreach (var m in mods.OfType <IApplicableToDrawableHitObjects>()) { m.ApplyToDrawableHitObjects(dho.Yield()); } } if (!lifetimeEntryMap.TryGetValue(hitObject, out var entry)) { lifetimeEntryMap[hitObject] = entry = CreateLifetimeEntry(hitObject); } dho.ParentHitObject = parent; dho.Apply(entry); })); }
public DefaultHitExplosion(DrawableHitObject judgedObject, HitResult result) { this.judgedObject = judgedObject; this.result = result; }
/// <summary> /// Creates a <see cref="HitObjectMask"/> for a specific <see cref="DrawableHitObject"/>. /// </summary> /// <param name="hitObject">The <see cref="DrawableHitObject"/> to create the overlay for.</param> public virtual HitObjectMask CreateMaskFor(DrawableHitObject hitObject) => null;
/// <summary> /// Invoked before a new <see cref="DrawableHitObject"/> is added to this <see cref="Playfield"/>. /// It is invoked only once even if the drawable is pooled and used multiple times for different <see cref="HitObject"/>s. /// </summary> /// <remarks> /// This is also invoked for nested <see cref="DrawableHitObject"/>s. /// </remarks> protected virtual void OnNewDrawableHitObject(DrawableHitObject drawableHitObject) { }
/// <summary> /// Creates a <see cref="SelectionBlueprint"/> for a specific <see cref="DrawableHitObject"/>. /// </summary> /// <param name="hitObject">The <see cref="DrawableHitObject"/> to create the overlay for.</param> public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null;
public DrawableNoteJudgement(JudgementResult result, DrawableHitObject judgedObject) : base(result, judgedObject) { }
public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
/// <summary> /// Associate a new result / object with this judgement. Should be called when retrieving a judgement from a pool. /// </summary> /// <param name="result">The applicable judgement.</param> /// <param name="judgedObject">The drawable object.</param> public void Apply([NotNull] JudgementResult result, [CanBeNull] DrawableHitObject judgedObject) { Result = result; JudgedObject = judgedObject; }
protected override void AddNestedHitObject(DrawableHitObject hitObject) { base.AddNestedHitObject(hitObject); bananaContainer.Add(hitObject); }
/// <summary> /// Creates a drawable which visualises a <see cref="Judgements.Judgement"/>. /// </summary> /// <param name="result">The judgement to visualise.</param> /// <param name="judgedObject">The object which was judged.</param> public DrawableJudgement(JudgementResult result, DrawableHitObject judgedObject) : this() { Apply(result, judgedObject); }
public override void Add(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column - firstColumnIndex).Add(h);
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement);
public override bool Remove(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column - firstColumnIndex).Remove(h);
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) { base.ApplyNormalVisibilityState(hitObject, state); applyState(hitObject, false); }
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result) { DrawableRushHitObject rushJudgedObject = (DrawableRushHitObject)judgedObject; RushJudgementResult rushResult = (RushJudgementResult)result; PlayerSprite.HandleResult(rushJudgedObject, result); const float judgement_time = 250f; // Display hit explosions for objects that allow it. if (result.IsHit && rushJudgedObject.DisplayExplosion) { var explosion = rushJudgedObject.CreateHitExplosion(); if (explosion != null) { // TODO: low priority, but the explosion should be added in a container // that has the hit object container to avoid this kinda hacky check. if (explosion.Depth <= 0) { overEffectContainer.Add(explosion); } else { underEffectContainer.Add(explosion); } } } // Display health point difference if the judgement result implies it. var pointDifference = rushResult.Judgement.HealthPointIncreaseFor(rushResult); if (pointDifference != 0) { var healthText = new SpriteText { RelativePositionAxes = Axes.Both, Position = new Vector2(0.75f, 0.5f), Origin = Anchor.Centre, Colour = pointDifference > 0 ? Color4.Green : Color4.Red, Text = $"{pointDifference:+0;-0}", Font = FontUsage.Default.With(size: 40), Scale = new Vector2(1.2f), }; overPlayerEffectsContainer.Add(healthText); healthText.ScaleTo(1f, judgement_time) .Then() .FadeOutFromOne(judgement_time) .MoveToOffset(new Vector2(0f, -20f), judgement_time) .Expire(true); } // Display judgement results in a drawable for objects that allow it. if (rushJudgedObject.DisplayResult) { DrawableJudgement judgementDrawable = null; // TODO: showing judgements based on the judged object suggests that // this may want to be inside the object class as well. switch (rushJudgedObject.HitObject) { case Sawblade sawblade: judgementDrawable = new DrawableRushJudgement(result, rushJudgedObject) { Origin = Anchor.Centre, Position = new Vector2(0f, judgementPositionForLane(sawblade.Lane.Opposite())), Scale = new Vector2(1.2f) }; break; case LanedHit lanedHit: judgementDrawable = new DrawableRushJudgement(result, rushJudgedObject) { Origin = Anchor.Centre, Position = new Vector2(0f, judgementPositionForLane(lanedHit.Lane)), Scale = new Vector2(1.5f) }; break; } if (judgementDrawable != null) { judgementContainer.Add(judgementDrawable); } } }
public OsuSelectionBlueprint(DrawableHitObject hitObject) : base(hitObject) { }
internal void ProcessHitObject(DrawableHitObject <BaseRpObject> returnObject) { HitObjectModsProcessor.ProcessHitObject(returnObject); }
private void judgement(DrawableHitObject h, JudgementInfo j) { HitExplosion explosion = new HitExplosion((OsuJudgementInfo)j, (OsuHitObject)h.HitObject); judgementLayer.Add(explosion); }
private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObject drawableObject) { string imageName = GetColumnSkinConfig <string>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteBodyImage)?.Value ?? $"mania-note{FallbackColumnIndex}L"; string lightImage = GetColumnSkinConfig <string>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightImage)?.Value ?? "lightingL"; float lightScale = GetColumnSkinConfig <float>(skin, LegacyManiaSkinConfigurationLookups.HoldNoteLightScale)?.Value ?? 1; // Create a temporary animation to retrieve the number of frames, in an effort to calculate the intended frame length. // This animation is discarded and re-queried with the appropriate frame length afterwards. var tmp = skin.GetAnimation(lightImage, true, false); double frameLength = 0; if (tmp is IFramedAnimation tmpAnimation && tmpAnimation.FrameCount > 0) { frameLength = Math.Max(1000 / 60.0, 170.0 / tmpAnimation.FrameCount); } light = skin.GetAnimation(lightImage, true, true, frameLength: frameLength).With(d => { if (d == null) { return; } d.Origin = Anchor.Centre; d.Blending = BlendingParameters.Additive; d.Scale = new Vector2(lightScale); }); if (light != null) { lightContainer = new HitTargetInsetContainer { Alpha = 0, Child = light }; } bodySprite = skin.GetAnimation(imageName, WrapMode.ClampToEdge, WrapMode.ClampToEdge, true, true).With(d => { if (d == null) { return; } if (d is TextureAnimation animation) { animation.IsPlaying = false; } d.Anchor = Anchor.TopCentre; d.RelativeSizeAxes = Axes.Both; d.Size = Vector2.One; d.FillMode = FillMode.Stretch; // Todo: Wrap }); if (bodySprite != null) { InternalChild = bodySprite; } direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); var holdNote = (DrawableHoldNote)drawableObject; isHitting.BindTo(holdNote.IsHitting); isHitting.BindValueChanged(onIsHittingChanged, true); }