internal void TriggerScoreIncrease(IncreaseScoreType hitType) { if (hitType != IncreaseScoreType.MissManiaHoldBreak) { hitScore.TextureArray = hitScoreTextures(hitType); hitScore.ResetAnimation(); hitScore.Transformations.Clear(); hitScore.Rotation = 0; float scale = 1; hitScore.Transformations.Add(new Transformation(TransformationType.Fade, hitScore.Alpha, 1, AudioEngine.Time, AudioEngine.Time + 20, EasingTypes.Out)); if (hitType == IncreaseScoreType.MissMania) { hitScore.Transformations.Add(new Transformation(TransformationType.Scale, scale * 1.2f, scale, AudioEngine.Time, AudioEngine.Time + 100, EasingTypes.Out)); hitScore.Transformations.Add(new Transformation(TransformationType.Rotation, 0, RNG.NextSingle(-0.1f, 0.1f), AudioEngine.Time, AudioEngine.Time + 100, EasingTypes.Out)); } else { hitScore.Transformations.Add(new Transformation(TransformationType.Scale, scale * 0.8f, scale, AudioEngine.Time + 0, AudioEngine.Time + 40, EasingTypes.None)); hitScore.Transformations.Add(new Transformation(TransformationType.Scale, scale, scale * 0.70f, AudioEngine.Time + 0, AudioEngine.Time + 80, EasingTypes.None)); hitScore.Transformations.Add(new Transformation(TransformationType.Scale, scale * 0.70f, scale * 0.4f, AudioEngine.Time + 180, AudioEngine.Time + 220, EasingTypes.In)); } hitScore.Transformations.Add(new Transformation(TransformationType.Fade, 1, 0, AudioEngine.Time + 180, AudioEngine.Time + 220, EasingTypes.In)); } }
internal IncreaseScoreType HitStart(HitCircleManiaLong h) { lastHitObject = h; IncreaseScoreType hitValue = h.HitStart(); return(hitValue); }
internal override void OnIncreaseScoreHit(IncreaseScoreType ist, double hpIncrease, HitObject h) { if (h == specialMovementNextFruit) { ResetMovementSpeed(); specialMovementNextFruit = null; } if (ist == IncreaseScoreType.FruitTickTiny || hpIncrease <= 0) { return; } ResetMovementSpeed(); //applies hyperdash checkDistanceToNextFruit(h as HitCircleFruits); WiimoteManager.Rumble(Player.KiaiActive ? 64 : 32); HpBar.KiBulge(); if (HpBar.CurrentHp > 180) { HpBar.KiExplode(); } }
internal override void IncreaseScoreHit(IncreaseScoreType value, HitObject ho) { if ((ho.IsHit && value != IncreaseScoreType.Ignore) || value == IncreaseScoreType.MissManiaHoldBreak) { player.UpdatePassing(value != IncreaseScoreType.MissMania && value != IncreaseScoreType.MissManiaHoldBreak); } base.IncreaseScoreHit(value, ho); }
internal override void IncreaseScoreHit(IncreaseScoreType value, HitObject ho) { if (ho.LastInCombo && ho.IsHit && value != IncreaseScoreType.Ignore) { player.UpdatePassing(value); } base.IncreaseScoreHit(value, ho); }
internal override void OnIncreaseScoreHit(IncreaseScoreType ist, double hpIncrease, HitObject h) { if (ist == IncreaseScoreType.TaikoDenDenComplete) { mascot.SetState(TaikoMascotStates.Clear, true); } base.OnIncreaseScoreHit(ist, hpIncrease, h); }
internal override void AddMeter(IncreaseScoreType score) { //Doesn't affect score - only combo if (score == IncreaseScoreType.MissManiaHoldBreak) { return; } base.AddMeter(score); }
internal override void IncreaseScoreHit(IncreaseScoreType value, HitObject ho) { if (value != IncreaseScoreType.Ignore) { player.UpdatePassing(value != IncreaseScoreType.Miss); } base.IncreaseScoreHit(value, ho); }
internal IncreaseScoreType Holding(HitCircleManiaLong h) { lastHitObject = h; IncreaseScoreType hitValue = h.Holding(); if (hitValue > IncreaseScoreType.Ignore) { OnHit(hitValue, "", h); } return(hitValue); }
/// <summary> /// When we have latency involved, we need to look at changing the autoplay replay /// to act as if a player was hitting notes. So we should check for any non-300s /// and apply then to the replay by warping some frames. /// </summary> private void AlterReplay(IncreaseScoreType type) { List <bReplayFrame> replay = autoScore.Replay; int currentFrame = InputManager.ReplayFrame + 1; while (currentFrame < replay.Count - 2) { bReplayFrame prev = replay[currentFrame - 1]; bReplayFrame curr = replay[currentFrame]; bReplayFrame next = replay[currentFrame + 1]; if (curr.mouseLeft) { if (prev.mouseLeft || next.mouseLeft || isLocalUserActiveAt(curr.time)) { currentFrame++; continue; //slider or spinner. } switch (type) { case IncreaseScoreType.Miss: curr.SetButtonStates(pButtonState.None); return; case IncreaseScoreType.Hit50: { int aim = (int)(player.hitObjectManager.HitWindow100 * 1.1f); if (curr.time - prev.time > aim) { curr.time -= aim; return; } } break; case IncreaseScoreType.Hit100: { int aim = (int)(player.hitObjectManager.HitWindow300 * 1.1f); if (curr.time - prev.time > aim) { curr.time -= aim; return; } } break; } } currentFrame++; } }
/// <summary> /// 鎬绘劅瑙夋病鍟ョ敤 /// </summary> /// <param name="type"></param> private void AddBound(IncreaseScoreType type) { switch (type) { case IncreaseScoreType.SpinnerSpin: case IncreaseScoreType.SpinnerSpinPoints: case IncreaseScoreType.SpinnerBonus: record_list.Add(type); break; default: throw new Exception("Unknown IncreaseScoreType for Spinner."); } }
internal override IncreaseScoreType Hit(HitObject h) { lastHitObject = h; IncreaseScoreType hitValue = h.Hit(); int index = hitObjects.BinarySearch(h); currentHitObjectIndex = index < 0 ? ~index : index; if (hitValue == IncreaseScoreType.Ignore) { return(hitValue); } if (perfectMod && hitValue < IncreaseScoreType.ManiaHit300) { hitValue = IncreaseScoreType.MissMania; } HitCircleMania be = (HitCircleMania)h; if (ManiaStage.Skin.SeparateScore) { be.Column.Host.TriggerScoreIncrease(hitValue); } else { foreach (StageMania stage in ManiaStage) { stage.TriggerScoreIncrease(hitValue); } } if (hitValue > IncreaseScoreType.Ignore) { Player.Instance.OnHitSuccess(h); be.Column.AddHitLight(); //Rest LN hitlight at the end of notes be.Column.HasLongHitLight = false; } OnHit(hitValue, "", h); return(hitValue); }
internal IncreaseScoreType GetActualScore() { IncreaseScoreType score = IncreaseScoreType.Ignore; if (rotationCount != lastRotationCount) { scoringRotationCount++; if (SkinManager.Current.SpinnerFrequencyModulate) { Bass.BASS_ChannelSetAttribute(AudioEngine.ch_spinnerSpin, BASSAttribute.BASS_ATTRIB_FREQ, Math.Min(100000, 20000 + (int) (40000 * ((float)scoringRotationCount / rotationRequirement)))); } if (scoringRotationCount > rotationRequirement + 3 && (scoringRotationCount - (rotationRequirement + 3)) % 2 == 0) { score = IncreaseScoreType.SpinnerBonus; AudioEngine.PlaySample(AudioEngine.s_SpinnerBonus, AudioEngine.VolumeSample); spriteBonus.Text = (1000 * (scoringRotationCount - (rotationRequirement + 3)) / 2).ToString(); spriteBonus.Transformations.Clear(); spriteBonus.Transformations.Add( new Transformation(TransformationType.Fade, 1, 0, AudioEngine.Time, AudioEngine.Time + 800)); spriteBonus.Transformations.Add( new Transformation(TransformationType.Scale, 1.28F, 2f, AudioEngine.Time, AudioEngine.Time + 800)); spriteBonus.Transformations[0].Easing = EasingTypes.In; spriteBonus.Transformations[1].Easing = EasingTypes.In; //Ensure we don't recycle this too early. spriteBonus.Transformations.Add( new Transformation(TransformationType.Fade, 0, 0, EndTime + 800, EndTime + 800)); } else if (scoringRotationCount > 1 && scoringRotationCount % 2 == 0) { score = IncreaseScoreType.SpinnerSpinPoints; } else if (scoringRotationCount > 1) { score = IncreaseScoreType.SpinnerSpin; } } lastRotationCount = rotationCount; return(score); }
//add combo internal IncreaseScoreType Holding() { IncreaseScoreType value = IncreaseScoreType.Ignore; if (lastScoreTime != -1 && AudioEngine.Time <= EndTime && AudioEngine.Time >= StartTime) { if (AudioEngine.Time - lastScoreTime >= JudgementMania.ComboIntv) { lastScoreTime += JudgementMania.ComboIntv; value = IncreaseScoreType.ComboAddition; } } /*if (AudioEngine.Time >= nextScoreTime && AudioEngine.Time <= EndTime && AudioEngine.Time >= StartTime) * { * nextScoreTime += JudgementBemani.ComboIntv; * value = IncreaseScoreType.ComboAddition; * }*/ return(value); }
private pTexture[] hitScoreTextures(IncreaseScoreType hitType) { switch (hitType) { case IncreaseScoreType.ManiaHit300g: return(hitTextures["300g"]); case IncreaseScoreType.ManiaHit300: return(hitTextures["300"]); case IncreaseScoreType.ManiaHit200: return(hitTextures["200"]); case IncreaseScoreType.ManiaHit100: return(hitTextures["100"]); case IncreaseScoreType.ManiaHit50: return(hitTextures["50"]); case IncreaseScoreType.MissMania: default: return(hitTextures["0"]); } }
internal override IncreaseScoreType Hit() { IncreaseScoreType ist = base.Hit(); return(ist <= 0 ? IncreaseScoreType.MissHpOnly : ist); }
internal override IncreaseScoreType GetScorePoints(Vector2 currentMousePos) { if (!InputManager.ScorableFrame) { return(0); } //First update the spinner velocity... Vector2 mouseVector = currentMousePos - SpriteCircleTop.drawPosition; double mouseAngle = Math.Atan2(mouseVector.Y, mouseVector.X); double mouseAngleDiff = mouseAngle - lastMouseAngle; if (mouseAngle - lastMouseAngle < -Math.PI) { mouseAngleDiff = (2 * Math.PI) + mouseAngle - lastMouseAngle; } else if (lastMouseAngle - mouseAngle < -Math.PI) { mouseAngleDiff = (-2 * Math.PI) - lastMouseAngle + mouseAngle; } double timeDiff = InputManager.LastScorableFrameTime > 0 ? AudioEngine.Time - InputManager.LastScorableFrameTime : GameBase.SIXTY_FRAME_TIME; double decay = Math.Pow(0.999, timeDiff); totalScoreFrameVariance = decay * totalScoreFrameVariance + (1 - decay) * timeDiff; if (mouseAngleDiff == 0) { velocityTheoretical = zeroCount++ < 1 ? velocityTheoretical / 3 : 0; } else { zeroCount = 0; if (!Player.Relaxing && ((InputManager.leftButton == ButtonState.Released && InputManager.rightButton == ButtonState.Released) || AudioEngine.Time < StartTime || AudioEngine.Time > EndTime)) { mouseAngleDiff = 0; } if (Math.Abs(mouseAngleDiff) < Math.PI) { if (HitObjectManager.ApplyModsToTime(totalScoreFrameVariance, hitObjectManager.ActiveMods) > GameBase.SIXTY_FRAME_TIME * 1.04f) { //after a certain lenience we need to stop allowing for SIXTY_FRAMEs and take frames for their actual elapsed time. //this is to handle the case where users are running at sub-60fps. //in a simple world, we could always use this timeDiff calculation, but due to historical reasons, //we were always slightly in the user's favour when calculating velocity here. velocityTheoretical = mouseAngleDiff / HitObjectManager.ApplyModsToTime(timeDiff, hitObjectManager.ActiveMods); } else { velocityTheoretical = mouseAngleDiff / GameBase.SIXTY_FRAME_TIME; } } else { velocityTheoretical = 0; } } lastMouseAngle = mouseAngle; //If we have actually progressed, let's return some score... if (rotationCount == lastRotationCount) { return(IncreaseScoreType.Ignore); } scoringRotationCount++; IncreaseScoreType score = IncreaseScoreType.Ignore; if (SkinManager.Current.SpinnerFrequencyModulate) { AudioEngine.UpdateSpinSample((float)scoringRotationCount / rotationRequirement); } if (scoringRotationCount > rotationRequirement + 3 && (scoringRotationCount - (rotationRequirement + 3)) % 2 == 0) { if (spriteGlow != null) { spriteGlow.FlashColour(Color.White, 200); } score = IncreaseScoreType.SpinnerBonus; if (!ModManager.CheckActive(Mods.Cinema)) { AudioEngine.PlaySample(@"spinnerbonus", AudioEngine.VolumeSample, SkinSource.All); } SpriteBonusCounter.Text = (1000 * (scoringRotationCount - (rotationRequirement + 3)) / 2).ToString(); SpriteBonusCounter.Transformations.Clear(); SpriteBonusCounter.Transformations.Add(new Transformation(TransformationType.Fade, 1, 0, AudioEngine.Time, AudioEngine.Time + 800)); SpriteBonusCounter.Transformations.Add(new Transformation(TransformationType.Scale, 2f, 1.28f, AudioEngine.Time, AudioEngine.Time + 800)); SpriteBonusCounter.Transformations[0].Easing = EasingTypes.Out; SpriteBonusCounter.Transformations[1].Easing = EasingTypes.Out; //Ensure we don't recycle this too early. SpriteBonusCounter.Transformations.Add(new Transformation(TransformationType.Fade, 0, 0, EndTime + 800, EndTime + 800)); } else if (scoringRotationCount > 1 && scoringRotationCount % 2 == 0) { score = IncreaseScoreType.SpinnerSpinPoints; } else if (scoringRotationCount > 1) { score = IncreaseScoreType.SpinnerSpin; } lastRotationCount = rotationCount; return(score); }
internal override void AddMeter(IncreaseScoreType score) { nextFadeTime = AudioEngine.Time + fade_delay; Show(); Color c; if (score < 0) { c = new Color(255, 9, 9); } else { switch (score & ~(IncreaseScoreType.NonScoreModifiers)) { case IncreaseScoreType.Hit300g: case IncreaseScoreType.Hit300k: case IncreaseScoreType.Hit300m: case IncreaseScoreType.Hit300: case IncreaseScoreType.TaikoDrumRoll: case IncreaseScoreType.TaikoDenDenHit: case IncreaseScoreType.TaikoDenDenComplete: c = colour300; break; case IncreaseScoreType.Hit100k: case IncreaseScoreType.Hit100m: case IncreaseScoreType.Hit100: case IncreaseScoreType.FruitTick: c = colour100; break; case IncreaseScoreType.Hit50m: case IncreaseScoreType.Hit50: case IncreaseScoreType.FruitTickTiny: c = colour50; break; case IncreaseScoreType.ManiaHit300g: c = new Color(255, 133, 0); break; case IncreaseScoreType.ManiaHit300: c = new Color(255, 209, 55); break; case IncreaseScoreType.ManiaHit200: c = new Color(121, 208, 32); break; case IncreaseScoreType.ManiaHit100: c = new Color(31, 104, 198); break; case IncreaseScoreType.ManiaHit50: c = new Color(109, 120, 135); break; default: return; } } if (iconIndex >= scoreIcons.Length) { iconIndex = 0; } Reset(); scoreIcons[iconIndex].InitialColour = c; scoreIcons[iconIndex].Alpha = 1; iconIndex++; }
internal override void IncreaseScoreHit(IncreaseScoreType value, HitObject h) { IncreaseScoreType scoringValue = value; if (scoringValue > 0) { scoringValue &= IncreaseScoreType.HitValuesOnly; } if (value < 0) { if (ModManager.CheckActive(Mods.NoFail)) { CurrentScore.CurrentCombo = (ushort)(ComboCounter.HitCombo = 0); CurrentScore.CountMiss++; return; } else { player.DoPass(); return; } } CurrentScore.MaxCombo = Math.Max(CurrentScore.MaxCombo, ++ComboCounter.HitCombo); CurrentScore.CurrentCombo = (ushort)ComboCounter.HitCombo; ScoreTarget ts = CurrentScore as ScoreTarget; float hitAccuracy = ((HitCircleOsuTarget)h).TargetAccuracy; ts.PositionTotal += hitAccuracy; int scoreMax = 0; switch (scoringValue) { case IncreaseScoreType.Hit300: case IncreaseScoreType.Hit300m: case IncreaseScoreType.Hit300k: case IncreaseScoreType.Hit300g: scoreMax = 300; CurrentScore.Count300++; break; case IncreaseScoreType.Hit100: case IncreaseScoreType.Hit100m: case IncreaseScoreType.Hit100k: scoreMax = 100; CurrentScore.Count100++; break; case IncreaseScoreType.Hit50: scoreMax = 50; CurrentScore.Count50++; break; } h.scoreValue = scoreMax; //todo: this should include some equation of distance over time, rather than current bpm. CurrentScore.TotalScore += (int)(hitAccuracy * scoreMax * AudioEngine.CurrentBPM / 120); }
internal virtual void AddMeter(IncreaseScoreType score) { }
/// <summary> /// When we have latency involved, we need to look at changing the autoplay replay /// to act as if a player was hitting notes. So we should check for any non-300s /// and apply then to the replay by warping some frames. /// </summary> private void AlterReplaySlider(IncreaseScoreType type) { //First check if we just want to increase the tick count... List <bReplayFrame> replay = autoScore.Replay; int currentFrame = InputManager.ReplayFrame + 1; int replayCount = replay.Count; if (currentFrame > replayCount - 1) { return; } int sliderCheckFrame = Math.Max(safeNoClickFrame, currentFrame); //Even if we already are in the middle of a slider, we should //rewind back to the start and utilise the rest of it. while (sliderCheckFrame < replayCount - 2 && replay[sliderCheckFrame + 1].mouseLeft) { sliderCheckFrame++; } safeNoClickFrame = sliderCheckFrame; while (currentFrame < replayCount - 2) { bReplayFrame prev = replay[currentFrame - 1]; bReplayFrame curr = replay[currentFrame]; bReplayFrame next = replay[currentFrame + 1]; if (curr.mouseLeft && next.mouseLeft && !prev.mouseLeft && !isLocalUserActiveAt(curr.time)) { //Found the start of a slider or spinner. //We need to confirm this is actually a slider though. //bool firstMatchRewindFound = sliderCheckFrame != currentFrame && first; //Is the first check in this loop and rewinding has been utilised. //if (!firstMatchRewindFound) //Rewinding current slider not used. Use currentFrame. // sliderCheckFrame = currentFrame; sliderCheckFrame = currentFrame; int searchTime = replay[sliderCheckFrame].time; SliderOsu found = player.hitObjectManager.hitObjects.Find(ho => ho.StartTime == searchTime) as SliderOsu; if (found == null) { currentFrame++; continue; //No slider or spinner. } //At this point we know we have a slider. //Now we need to choose how to change the replay depending on the type of //penalty we are planning to deal. switch (type) { case IncreaseScoreType.Miss: //The slider should be TOTALLY missed. //We can't do this if we have already started on a slider that //has already had a non-miss... /*if (firstMatchRewindFound && found.sliderTicksMissed == 0) * { * currentFrame++; * continue; * }*/ while (curr.mouseLeft) { //No mouse control over the whole slider is required. curr.SetButtonStates(pButtonState.None); if (currentFrame == replayCount - 1) { return; } curr = replay[++currentFrame]; } return; case IncreaseScoreType.Hit50: case IncreaseScoreType.Hit100: case IncreaseScoreType.Hit300: { int possibleCount; if (type == IncreaseScoreType.Hit50) { //In case of a 50, we can miss a minimum of 50%. possibleCount = (found.sliderScoreTimingPoints.Count + 1) / 2 == (found.sliderScoreTimingPoints.Count + 1) / 2f ? (found.sliderScoreTimingPoints.Count + 1) / 2 : (found.sliderScoreTimingPoints.Count + 1) / 2 + 1; //possibleCount = found.sliderScoreTimingPoints.Count; } else if (type == IncreaseScoreType.Hit100) { //In case of a 100, we can miss a maximum of 50%. possibleCount = 1; //TOO LENIANT } else { return; } //If the slider is already partway through, we should remove any ticks which have already been consumed. possibleCount -= found.sliderTicksHit; if (possibleCount <= 0) { currentFrame++; continue; } bool firstTick = true; int firstTickEndTime = curr.time + Math.Min(found.sliderScoreTimingPoints[0], player.hitObjectManager.HitWindow50); while (curr.time <= found.EndTime && possibleCount > 0) { if (firstTick) { if (curr.time < firstTickEndTime) { curr.SetButtonStates(pButtonState.None); } else { firstTick = false; possibleCount--; } } if (!firstTick) { bool containsTimingPoint = found.sliderScoreTimingPoints.FindIndex( tp => curr.time <= tp && next.time > tp) >= 0; if (containsTimingPoint) { if (possibleCount > 0) { possibleCount--; curr.SetButtonStates(pButtonState.None); next.SetButtonStates(pButtonState.None); Debug.Print(" Consumed 1 tick (remaining to consume " + possibleCount + ")"); } else { return; } } } if (currentFrame == replayCount - 1) { break; } curr = replay[++currentFrame]; next = replay[currentFrame + 1]; } } Debug.Print(" Slider exhausted..."); return; } } currentFrame++; } }
internal override IncreaseScoreType Hit(HitObject h) { IncreaseScoreType val = base.Hit(h); if (val > 0) { float rotation = (float)(targetRandom.NextDouble() * Math.PI * 2); for (int i = 0; i < 5; i++) { double actualPiceAngle = piece_angles[i] + rotation; double velocity = 300 + targetRandom.NextDouble() * 100; switch (val & IncreaseScoreType.BaseHitValuesOnly) { case IncreaseScoreType.Hit100: velocity *= 0.4; break; case IncreaseScoreType.Hit50: velocity *= 0.01; break; } velocity *= Math.Pow(((HitCircleOsuTarget)h).TargetAccuracy, 4); Vector2 gravityVector = new Vector2( (float)(velocity * Math.Cos(actualPiceAngle)), (float)(velocity * Math.Sin(actualPiceAngle)) ); const int duration = 600; const int weight = 100; const float scale = 0.8f; pSprite piece = new pSprite(TextureManager.Load(@"target-pt-" + (i + 1)), Fields.Gamefield, Origins.Centre, Clocks.AudioOnce, h.EndPosition, 0.99f, false, h.Colour); piece.Rotation = rotation; piece.ScaleTo(piece.Scale * scale, duration); piece.FadeOutFromOne(duration); spriteManager.Add(piece); physics.Add(piece, gravityVector).weight = weight; piece = new pSprite(TextureManager.Load(@"targetoverlay-pt-" + (i + 1)), Fields.Gamefield, Origins.Centre, Clocks.AudioOnce, h.EndPosition, 1, false, Color.White); piece.Rotation = rotation; piece.ScaleTo(piece.Scale * scale, duration); piece.FadeOutFromOne(duration); spriteManager.Add(piece); physics.Add(piece, gravityVector).weight = weight; } } return(val); }
public ScoreChange(IncreaseScoreType value, bool increaseCombo, bool addComboMultiplier) { HitValue = value; ComboIncrease = increaseCombo; ComboMultiplier = addComboMultiplier; }
internal override IncreaseScoreType Hit() { //Small hit, do as per normal //If large, we expect to reach here twice. //Record the time of the first button press and if the second is within 30ms, double the value. int accuracy = Math.Abs(AudioEngine.Time - StartTime); if (accuracy < hitObjectManager.HitWindow300 && !wrongButton) { HitValue = IncreaseScoreType.Hit300; } else if (accuracy < hitObjectManager.HitWindow100 && !wrongButton) { HitValue = IncreaseScoreType.Hit100; } else { HitValue = IncreaseScoreType.Miss; } if (!hitOnce) { if (taikoLarge && HitValue != IncreaseScoreType.Miss) { if (bothButtonsInstantaneous) { //Both buttons have been hit at the same time in the same frame. //Easy. If this always happened, things would be simple. IsHit = true; IsHitTwice = true; HitValue |= IncreaseScoreType.TaikoLargeHitBoth; } else { //Only one hit was found. We set hitOnce but don't mark this as hit. //If HitTest() allows the second hit, it will reach the fallthrough condition below.. hitOnce = true; hitOnceValue = HitValue; hitOnceTime = AudioEngine.Time; HitValue |= IncreaseScoreType.TaikoLargeHitFirst; } } else { IsHit = true; } if (HitValue > 0) { PlaySound(); } Arm(HitValue > 0); return(HitValue); } if (taikoLarge) { IsHit = true; if (secondHitAllowable) { //If we got here, it's a large hit which has only been hit once. IsScorable = false; if (AudioEngine.Time - hitOnceTime < second_hit_window && lastlastButton1 != lastButton1) { IsHitTwice = true; return(hitOnceValue | IncreaseScoreType.TaikoLargeHitSecond); } } } return(IncreaseScoreType.Ignore); }