protected override void PostProcessing() { //Play-mode specific transformations if (GameBase.Mode == OsuModes.Edit) { return; } hitObjectsCount = hitObjects.Count; if (hitObjectsCount == 0) { return; } Vector2 hitLocation = HIT_LOCATION; int inLength = GameBase.WindowManager.WidthScaled - 40; const int outLengthTimewise = 300; const int outLength = 300; double multipier = 1; bool hidden = ModManager.CheckActive(ActiveMods, Mods.Hidden) && !ModManager.CheckActive(ActiveMods, Mods.HardRock); if (hidden) { inLength = WindowManager.DEFAULT_WIDTH - 40; spriteManager.SetVisibleArea(new RectangleF(0, 0, WindowManager.DEFAULT_WIDTH, GameBase.WindowManager.HeightScaled)); } if (ModManager.CheckActive(ActiveMods, Mods.HardRock)) { multipier *= 1.4f * GameBase.WindowManager.WidthScaled / WindowManager.DEFAULT_WIDTH; } else if (ModManager.CheckActive(ActiveMods, Mods.Easy)) { multipier *= 0.8f; } for (int i = 0; i < hitObjectsCount; i++) { HitObject currHitObject = hitObjects[i]; currHitObject.ModifyPosition(hitLocation); double outLengthCurr = outLength; double sv = SliderVelocityAt(currHitObject.StartTime) * multipier; if (currHitObject is SliderTaiko) { SliderTaiko s = (SliderTaiko)currHitObject; //Adjust the length before calculation to allow for the difficulty multiplier. s.UpdateCalculations(true, multipier); outLengthCurr += s.SpatialLength; } int inMsLength = (int)(inLength / sv * 1000); int outMsLength = (int)(outLengthTimewise / sv * 1000); SpinnerTaiko st = currHitObject as SpinnerTaiko; if (st != null) { //special handling of taiko spinners, where we need to show a warning icon on the taiko bar. pSprite s = st.WarningIcon; const int appearTime = 200; s.Transformations.Add( new Transformation(new Vector2(s.Position.X + inLength, s.Position.Y), new Vector2(s.Position.X, s.Position.Y), currHitObject.StartTime - inMsLength, currHitObject.StartTime)); s.Transformations.Add( new Transformation(new Vector2(s.Position.X, s.Position.Y), new Vector2(256, 196), currHitObject.StartTime, currHitObject.StartTime + appearTime)); s.Transformations.Add( new Transformation(TransformationType.Scale, 1, 3, currHitObject.StartTime, currHitObject.StartTime + appearTime, EasingTypes.Out)); s.Transformations.Add(new Transformation(TransformationType.Fade, 1, 0, currHitObject.StartTime, currHitObject.StartTime + appearTime)); } else { for (int j = 0; j < currHitObject.SpriteCollection.Count; j++) { pSprite s = currHitObject.SpriteCollection[j]; s.Transformations.Add( new Transformation(new Vector2(s.Position.X + inLength, s.Position.Y), new Vector2(s.Position.X, s.Position.Y), currHitObject.StartTime - inMsLength, currHitObject.StartTime)); s.Transformations.Add( new Transformation(new Vector2(s.Position.X, s.Position.Y), new Vector2(s.Position.X - (float)outLengthCurr, s.Position.Y), currHitObject.StartTime, currHitObject.EndTime + outMsLength)); } } } int lastHitTime = hitObjects[hitObjectsCount - 1].EndTime + 1; List <ControlPoint> tp = Beatmap.TimingPoints; if (tp == null || tp.Count == 0) { return; } int ctp = 0; double time = tp[0].Offset; double measureLength = tp[0].BeatLength * (int)tp[0].TimeSignature; //barline time closest to 0 offset time -= measureLength * (int)(time / measureLength); //start barlines from positive offset if (time < 0) { time += measureLength; } pTexture tbl = TextureManager.Load(@"taiko-barline", SkinSource.Osu); //Precalculation of barlines. while (time <= lastHitTime) { ControlPoint currpoint = tp[ctp]; if (time > currpoint.Offset || (currpoint.EffectFlags & EffectFlags.OmitFirstBarLine) == 0) { pSprite barLine = new pSprite(tbl, Fields.GamefieldWide, Origins.Centre, Clocks.Audio, hitLocation, 0.0002f, false, Color.White); barLine.Scale = 0.88f; int intTime = (int)time; double sv = SliderVelocityAt(intTime) * multipier; int inMsLength = (int)(inLength / sv * 1000); int outMsLength = (int)(outLengthTimewise / sv * 1000); spriteManager.Add(barLine); barLine.Transformations.Add( new Transformation(new Vector2(barLine.Position.X + inLength, barLine.Position.Y), new Vector2(barLine.Position.X, barLine.Position.Y), intTime - inMsLength, intTime)); barLine.Transformations.Add( new Transformation(new Vector2(barLine.Position.X, barLine.Position.Y), new Vector2(barLine.Position.X - outLength, barLine.Position.Y), intTime, intTime + outMsLength)); } double bl = currpoint.BeatLength; if (bl < 800) { bl *= (int)currpoint.TimeSignature; } time += bl; if (ctp + 1 < tp.Count && time >= tp[ctp + 1].Offset) { ctp++; time = tp[ctp].Offset; } } }