From 80ca43b46e49fa29966605ee91bc930df5b85bf7 Mon Sep 17 00:00:00 2001 From: SrtHero278 Date: Mon, 11 May 2026 19:44:59 -0700 Subject: [PATCH] shits break combo because read desc this engine is spam and get away with it central like i struggled to hit a shit no joke and i did get owner approval to do this --- source/funkin/game/PlayState.hx | 30 ++++++++++++++++++--- source/funkin/game/scoring/RatingManager.hx | 29 +++++++++++++++++--- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 59bd5456..b4e7a290 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -623,6 +623,18 @@ class PlayState extends MusicBeatState curRating = event.rating; } + private function onRatingChange(rating:Rating) { + if (!hits.exists(rating.name)) + hits.set(rating.name, 0); + + if (Options.ghostTapping) { + comboBreaks = false; + for (rating in ratingManager.ratingData) + comboBreaks = comboBreaks || rating.breaksCombo; + } else + comboBreaks = true; + } + private inline function set_health(v:Float) return health = FlxMath.bound(v, 0, maxHealth); private inline function set_maxHealth(v:Float) { @@ -690,6 +702,14 @@ class PlayState extends MusicBeatState detailsText = isStoryMode ? ("Story Mode: " + storyWeek.name) : "Freeplay"; for (rating in [for (i in ratingManager.ratingData) i.name]) hits.set(rating, 0); // Ensure all keys exist as to prevent null errors. + if (Options.ghostTapping) { + comboBreaks = false; + for (rating in ratingManager.ratingData) + comboBreaks = comboBreaks || rating.breaksCombo; + } else + comboBreaks = true; + ratingManager.onRatingAdded.add(onRatingChange); + ratingManager.onRatingRemoved.add(onRatingChange); // Checks if cutscene files exists var cutscenePath = Paths.script('songs/${SONG.meta.name}/cutscene'); @@ -1946,9 +1966,9 @@ class PlayState extends MusicBeatState var event:NoteHitEvent; if (strumLine != null && !strumLine.cpu) - event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, rating.score, note.isSustainNote ? null : rating.accuracy, 0.023, rating.name, Options.splashesEnabled && !note.isSustainNote && rating.splash, 0.5, true, 0.7, true, true, iconP1); + event = EventManager.get(NoteHitEvent).recycle(rating.breaksCombo, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, rating.score, note.isSustainNote ? null : rating.accuracy, rating.health, rating.name, Options.splashesEnabled && !note.isSustainNote && rating.splash, 0.5, true, 0.7, true, true, iconP1); else - event = EventManager.get(NoteHitEvent).recycle(false, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, rating.name, false, 0.5, true, 0.7, true, true, iconP2); + event = EventManager.get(NoteHitEvent).recycle(rating.breaksCombo, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, rating.name, false, 0.5, true, 0.7, true, true, iconP2); event.deleteNote = !note.isSustainNote; // work around, to allow sustain notes to be deleted event = scripts.event(strumLine != null && !strumLine.cpu ? "onPlayerHit" : "onDadHit", event); strumLine.onHit.dispatch(event); @@ -1964,7 +1984,11 @@ class PlayState extends MusicBeatState totalAccuracyAmount += event.accuracy; updateRating(); } - if (event.countAsCombo) combo++; + if (event.misses) { + combo = 0; + misses++; + } else if (event.countAsCombo) + combo++; if (event.showRating || (event.showRating == null && event.player)) { diff --git a/source/funkin/game/scoring/RatingManager.hx b/source/funkin/game/scoring/RatingManager.hx index a538e79a..ecab6641 100644 --- a/source/funkin/game/scoring/RatingManager.hx +++ b/source/funkin/game/scoring/RatingManager.hx @@ -2,6 +2,7 @@ package funkin.game.scoring; import funkin.game.scoring.*; import funkin.game.scoring.HitWindowData.WindowPreset; +import flixel.util.FlxSignal; import haxe.ds.StringMap; @@ -10,6 +11,9 @@ import haxe.ds.StringMap; */ class RatingManager { + public var onRatingAdded:FlxTypedSignalVoid> = new FlxTypedSignal(); + public var onRatingRemoved:FlxTypedSignalVoid> = new FlxTypedSignal(); + public var hitWindows:StringMap; public var ratingData:Array = []; public var lastHitWindow:Float = -1; @@ -50,9 +54,9 @@ class RatingManager } addRating({name: "sick", window: getWindow("sick"), accuracy: 1, score: 300, splash: true}); - addRating({name: "good", window: getWindow("good"), accuracy: 0.75, score: 200}); - addRating({name: "bad", window: getWindow("bad"), accuracy: 0.45, score: 100}); - addRating({name: "shit", window: getWindow("shit"), accuracy: 0.25, score: 50}); + addRating({name: "good", window: getWindow("good"), accuracy: 0.75, score: 200, health: 0.015}); + addRating({name: "bad", window: getWindow("bad"), accuracy: 0.45, score: 100, health: 0}); + addRating({name: "shit", window: getWindow("shit"), accuracy: 0.25, score: 50, health: -0.05, breaksCombo: true}); } public function addRating(data:Dynamic) @@ -71,7 +75,9 @@ class RatingManager window: window, accuracy: data.accuracy != null ? data.accuracy : 1, score: data.score != null ? data.score : 0, + health: data.health != null ? data.health : 0.023, splash: data.splash == true, + breaksCombo: data.breaksCombo == true, hittable: data.hittable != null ? data.hittable : true }; @@ -86,13 +92,18 @@ class RatingManager ratingData.push(newRating); ratingData.sort((a, b) -> Reflect.compare(a.window, b.window)); + onRatingAdded.dispatch(newRating); } public function removeRating(name:String):Void { if (name == null) return; name = name.toLowerCase(); - ratingData = ratingData.filter(r -> r.name != name); + var toRemove = ratingData.filter(r -> r.name == name); + for (rating in toRemove) { + ratingData.remove(rating); + onRatingRemoved.dispatch(rating); + } } public function getHitWindow(name:String):Float @@ -126,11 +137,21 @@ final class Rating */ public var score:Int = 0; + /** + * Amount of health given when earning this rating. + */ + public var health:Float = 0.023; + /** * If this rating was hit, a note splash will appear. */ @:optional public var splash:Bool = false; + /** + * Whether the rating will break your combo or not. + */ + @:optional public var breaksCombo:Bool = false; + /** * Whether the rating is hittable or not. */