diff --git a/assets/data/freeplaySonglist.json b/assets/data/freeplaySonglist.json index cf387481..ca58af47 100644 --- a/assets/data/freeplaySonglist.json +++ b/assets/data/freeplaySonglist.json @@ -1,6 +1,10 @@ { "addOGSongs": false, "songs": [ + { + "name": "test", + "icon": "bf" + }, { "name": "Tutorial", "icon": "gf", diff --git a/assets/data/scripts/pixel.hx b/assets/data/scripts/pixel.hx index c21c2bf0..cef420ee 100644 --- a/assets/data/scripts/pixel.hx +++ b/assets/data/scripts/pixel.hx @@ -1,10 +1,12 @@ +import funkin.scripting.events.NoteHitEvent; + public var pixelNotesForBF = true; public var pixelNotesForDad = true; public var enablePixelUI = true; public var enableCameraHacks = true; public var enablePauseMenu = true; -var daPixelZoom = 6; +static var daPixelZoom = 6; /** * UI @@ -49,7 +51,7 @@ function onCountdown(event) { if (event.soundPath != null) event.soundPath = 'pixel/' + event.soundPath; event.antialiasing = false; - event.scale = 6; + event.scale = daPixelZoom; event.spritePath = switch(event.swagCounter) { case 0: null; case 1: 'stages/school/ui/ready'; @@ -58,6 +60,16 @@ function onCountdown(event) { }; } +function onPlayerHit(event:NoteHitEvent) { + if (!enablePixelUI) return; + event.ratingPrefix = "stages/school/ui/"; + event.ratingScale = daPixelZoom * 0.7; + event.ratingAntialiasing = false; + + event.numScale = daPixelZoom; + event.numAntialiasing = false; +} + /** * CAMERA HACKS!! */ @@ -74,14 +86,14 @@ function createPost() { newNoteCamera.bgColor = 0; // transparent FlxG.cameras.add(newNoteCamera, false); - var pixelSwagWidth = Note.swagWidth + (6 - (Note.swagWidth % 6)); + var pixelSwagWidth = Note.swagWidth + (daPixelZoom - (Note.swagWidth % daPixelZoom)); // TODO: multikey support?? for(s in 0...4) { var i = 0; for(str in [cpuStrums.members[s], playerStrums.members[s]]) { // TODO: middlescroll??? str.x = (FlxG.width * (0.25 + (0.5 * i))) + (pixelSwagWidth * (s - 2)); - str.x -= str.x % 6; + str.x -= str.x % daPixelZoom; str.cameras = [newNoteCamera]; i++; } @@ -92,6 +104,7 @@ function createPost() { makeCameraPixely(camGame); makeCameraPixely(newNoteCamera); + defaultCamZoom /= daPixelZoom; } } @@ -100,8 +113,7 @@ function createPost() { */ public function makeCameraPixely(cam) { cam.pixelPerfectRender = true; - cam.zoom /= Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y) * 6; - defaultCamZoom /= 6; + cam.zoom /= Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y) * daPixelZoom; var shad = new CustomShader('pixelZoomShader'); cam.addShader(shad); @@ -120,15 +132,15 @@ var pixellyShaders = []; function updatePost(elapsed) { for(e in pixellyCameras) { if (!e.exists) continue; - e.zoom = 1 / 6 / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); + e.zoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); } for(e in pixellyShaders) { - e.pixelZoom = 1 / 6 / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); + e.pixelZoom = 1 / daPixelZoom / Math.min(FlxG.scaleMode.scale.x, FlxG.scaleMode.scale.y); } if (enableCameraHacks) { notes.forEach(function(n) { - n.y -= n.y % 6; + n.y -= n.y % daPixelZoom; }); } } \ No newline at end of file diff --git a/assets/sounds/menu/volume.mp3 b/assets/sounds/menu/volume.mp3 new file mode 100644 index 00000000..8a5e8664 Binary files /dev/null and b/assets/sounds/menu/volume.mp3 differ diff --git a/assets/sounds/menu/volume.ogg b/assets/sounds/menu/volume.ogg new file mode 100644 index 00000000..e5697c93 Binary files /dev/null and b/assets/sounds/menu/volume.ogg differ diff --git a/buildnumber.txt b/buildnumber.txt index a899ac6c..c659825d 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -1160 \ No newline at end of file +1163 \ No newline at end of file diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 6b55e7f4..fa5b4a4c 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -93,7 +93,7 @@ class PlayState extends MusicBeatState public var notes:NoteGroup; public var strumLine:FlxSprite; - public var curSection:Int = 0; + public var ratingNum:Int = 0; public var camFollow:FlxObject; @@ -1073,144 +1073,6 @@ class PlayState extends MusicBeatState public var comboGroup:FlxSpriteGroup; - private function popUpScore(strumtime:Float, score:Int = 350):Void - { - var noteDiff:Float = Math.abs(strumtime - Conductor.songPosition); - vocals.volume = 1; - - var placement:String = Std.string(combo); - // - - var rating:FlxSprite = new FlxSprite(-40, -60); - - var daRating:String = "sick"; - - if (noteDiff > Conductor.safeZoneOffset * 0.9) - { - daRating = 'shit'; - score = 50; - } - else if (noteDiff > Conductor.safeZoneOffset * 0.75) - { - daRating = 'bad'; - score = 100; - } - else if (noteDiff > Conductor.safeZoneOffset * 0.2) - { - daRating = 'good'; - score = 200; - } - - songScore += score; - - /* if (combo > 60) - daRating = 'sick'; - else if (combo > 12) - daRating = 'good' - else if (combo > 4) - daRating = 'bad'; - */ - - var prefix:String = ""; - var suffix:String = ''; - - if (curStage.startsWith('school')) - { - prefix = 'weeb/pixelUI/'; - suffix = '-pixel'; - } - - rating.loadGraphic(Paths.image('game/score/$prefix$daRating$suffix')); - rating.acceleration.y = 550; - rating.velocity.y -= FlxG.random.int(140, 175); - rating.velocity.x -= FlxG.random.int(0, 10); - - var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image('game/score/${prefix}combo$suffix')); - comboSpr.acceleration.y = 600; - comboSpr.velocity.y -= 150; - comboSpr.velocity.x += FlxG.random.int(1, 10); - - comboGroup.add(comboSpr); - comboGroup.add(rating); - - if (!curStage.startsWith('school')) - { - rating.scale.set(0.7, 0.7); - rating.antialiasing = true; - comboSpr.scale.set(0.7, 0.7); - comboSpr.antialiasing = true; - } - else - { - rating.setGraphicSize(Std.int(rating.width * daPixelZoom * 0.7)); - comboSpr.setGraphicSize(Std.int(comboSpr.width * daPixelZoom * 0.7)); - } - - comboSpr.updateHitbox(); - rating.updateHitbox(); - - var separatedScore:String = Std.string(combo).addZeros(3); - - - for (i in 0...separatedScore.length) - { - if (combo < 10 && combo != 0) - break; - - var e = separatedScore.charAt(i); - - var numScore:FlxSprite = new FlxSprite((43 * i) - 90, 80).loadGraphic(Paths.image('game/${prefix}score/num$e$suffix')); - - if (!curStage.startsWith('school')) - { - numScore.antialiasing = true; - numScore.setGraphicSize(Std.int(numScore.width * 0.5)); - } - else - { - numScore.setGraphicSize(Std.int(numScore.width * daPixelZoom)); - } - numScore.updateHitbox(); - - numScore.acceleration.y = FlxG.random.int(200, 300); - numScore.velocity.y -= FlxG.random.int(140, 160); - numScore.velocity.x = FlxG.random.float(-5, 5); - - comboGroup.add(numScore); - - FlxTween.tween(numScore, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - comboGroup.remove(numScore, true); - numScore.destroy(); - }, - startDelay: Conductor.crochet * 0.002 - }); - } - /* - trace(combo); - trace(separatedScore); - */ - - FlxTween.tween(rating, {alpha: 0}, 0.2, { - startDelay: Conductor.crochet * 0.001 - }); - - FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { - onComplete: function(tween:FlxTween) - { - comboGroup.remove(comboSpr, true); - comboGroup.remove(rating, true); - comboSpr.destroy(); - - rating.destroy(); - }, - startDelay: Conductor.crochet * 0.001 - }); - - curSection += 1; - } - private function keyShit():Void { var pressed = [controls.NOTE_LEFT, controls.NOTE_DOWN, controls.NOTE_UP, controls.NOTE_RIGHT]; @@ -1307,18 +1169,118 @@ class PlayState extends MusicBeatState if (!note.wasGoodHit) { note.wasGoodHit = true; + + /** + * CALCULATES RATING + */ + var noteDiff = Math.abs(Conductor.songPosition - note.strumTime); + var daRating:String = "sick"; + var score:Int = 300; + var accuracy:Float = 1; + + if (noteDiff > Conductor.safeZoneOffset * 0.9) + { + daRating = 'shit'; + score = 50; + accuracy = 0.25; + } + else if (noteDiff > Conductor.safeZoneOffset * 0.75) + { + daRating = 'bad'; + score = 100; + accuracy = 0.45; + } + else if (noteDiff > Conductor.safeZoneOffset * 0.2) + { + daRating = 'good'; + score = 200; + accuracy = 0.75; + } var event:NoteHitEvent; if (note.mustPress) - event = scripts.event("onPlayerHit", new NoteHitEvent(note, boyfriend, true, note.noteType, note.strumID, note.noteData > 0 ? 0.023 : 0.004, note.animSuffix)); + event = scripts.event("onPlayerHit", new NoteHitEvent(note, boyfriend, true, note.noteType, note.strumID, note.noteData > 0 ? 0.023 : 0.004, score, note.animSuffix, daRating, accuracy, "game/score/", '')); else - event = scripts.event("onDadHit", new NoteHitEvent(note, dad, false, note.noteType, note.strumID, 0, note.animSuffix)); + event = scripts.event("onDadHit", new NoteHitEvent(note, dad, false, note.noteType, note.strumID, 0, 0, note.animSuffix, daRating, null, "game/score/", '')); if (!event.cancelled) { - if (event.player && !note.isSustainNote) + if (event.countAsCombo) combo++; + + if (event.showRating || (event.showRating == null && event.player && !note.isSustainNote)) { - combo++; - popUpScore(note.strumTime, event.score); + var rating:FlxSprite = new FlxSprite(-40, -60); + + songScore += score; + + rating.loadGraphic(Paths.image('${event.ratingPrefix}$daRating${event.ratingSuffix}')); + rating.acceleration.y = 550; + rating.velocity.y -= FlxG.random.int(140, 175); + rating.velocity.x -= FlxG.random.int(0, 10); + + var comboSpr:FlxSprite = new FlxSprite().loadGraphic(Paths.image('${event.ratingPrefix}combo${event.ratingSuffix}')); + comboSpr.acceleration.y = 600; + comboSpr.velocity.y -= 150; + comboSpr.velocity.x += FlxG.random.int(1, 10); + + comboGroup.add(comboSpr); + comboGroup.add(rating); + + rating.scale.set(event.ratingScale, event.ratingScale); + rating.antialiasing = event.ratingAntialiasing; + comboSpr.scale.set(event.ratingScale, event.ratingScale); + comboSpr.antialiasing = event.ratingAntialiasing; + + comboSpr.updateHitbox(); + rating.updateHitbox(); + + var separatedScore:String = Std.string(combo).addZeros(3); + + + for (i in 0...separatedScore.length) + { + if (combo < 10 && combo != 0) + break; + + var e = separatedScore.charAt(i); + + var numScore:FlxSprite = new FlxSprite((43 * i) - 90, 80).loadGraphic(Paths.image('${event.ratingPrefix}num$e${event.ratingSuffix}')); + numScore.antialiasing = event.numAntialiasing; + numScore.scale.set(event.numScale, event.numScale); + numScore.updateHitbox(); + + numScore.acceleration.y = FlxG.random.int(200, 300); + numScore.velocity.y -= FlxG.random.int(140, 160); + numScore.velocity.x = FlxG.random.float(-5, 5); + + comboGroup.add(numScore); + + FlxTween.tween(numScore, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + comboGroup.remove(numScore, true); + numScore.destroy(); + }, + startDelay: Conductor.crochet * 0.002 + }); + } + + FlxTween.tween(rating, {alpha: 0}, 0.2, { + startDelay: Conductor.crochet * 0.001 + }); + + FlxTween.tween(comboSpr, {alpha: 0}, 0.2, { + onComplete: function(tween:FlxTween) + { + comboGroup.remove(comboSpr, true); + comboGroup.remove(rating, true); + comboSpr.destroy(); + + rating.destroy(); + }, + startDelay: Conductor.crochet * 0.001 + }); + + ratingNum += 1; } health += event.healthGain; diff --git a/source/funkin/menus/FreeplayState.hx b/source/funkin/menus/FreeplayState.hx index 8bfe19d2..bedbd543 100644 --- a/source/funkin/menus/FreeplayState.hx +++ b/source/funkin/menus/FreeplayState.hx @@ -273,7 +273,7 @@ class FreeplaySonglist { } - private function _addJSONSongs(songs:Array) { + private function _addJSONSongs(songs:Array, source:Bool = false) { if (songs != null && songs is Array) { for(e in songs) { if (e is Dynamic) { @@ -283,7 +283,7 @@ class FreeplaySonglist { this.songs.push(new SongMetadata(e.name, e.icon.getDefault("bf"), - CoolUtil.getColorFromDynamic(e.color).getDefault(FreeplayState.defaultColor), e.difficulties)); + CoolUtil.getColorFromDynamic(e.color).getDefault(FreeplayState.defaultColor), e.difficulties, source)); } } } @@ -298,10 +298,10 @@ class FreeplaySonglist { try { var json:FreeplayJSON = Json.parse(Assets.getText(jsonPath)); var addOGSongs = CoolUtil.getDefault(json.addOGSongs, true); - songList._addJSONSongs(json.songs); + songList._addJSONSongs(json.songs, jsonPath == baseJsonPath); if (addOGSongs && (jsonPath != baseJsonPath)) { var json:FreeplayJSON = Json.parse(Assets.getText(baseJsonPath)); - songList._addJSONSongs(json.songs); + songList._addJSONSongs(json.songs, true); } } @@ -328,7 +328,7 @@ class SongMetadata public var songCharacter:String = ""; public var difficulties:Array = ["EASY", "NORMAL", "HARD"]; - public function new(song:String, songCharacter:String, color:FlxColor, ?difficulties:Array) + public function new(song:String, songCharacter:String, color:FlxColor, ?difficulties:Array, fromSource:Bool = false) { this.songName = song; this.color = color; @@ -336,7 +336,7 @@ class SongMetadata if (difficulties != null && difficulties.length > 0) { this.difficulties = difficulties; } else { - this.difficulties = difficulties = [for(f in Paths.getFolderContent('data/charts/${song}/', false)) if (Path.extension(f = f.toUpperCase()) == "JSON") Path.withoutExtension(f)]; + this.difficulties = difficulties = [for(f in Paths.getFolderContent('data/charts/${song}/', false, false, fromSource)) if (Path.extension(f = f.toUpperCase()) == "JSON") Path.withoutExtension(f)]; if (difficulties.length == 3) { var hasHard = false, hasNormal = false, hasEasy = false; for(d in difficulties) { diff --git a/source/funkin/options/Options.hx b/source/funkin/options/Options.hx index 6cf0d14d..45b269a8 100644 --- a/source/funkin/options/Options.hx +++ b/source/funkin/options/Options.hx @@ -21,6 +21,7 @@ class Options public static var fpsCounter:Bool = true; public static var autoPause:Bool = true; public static var antialiasing:Bool = true; + public static var volume:Float = 1; /** * PLAYER 1 CONTROLS @@ -167,9 +168,11 @@ class Options PlayerSettings.player1.setKeyboardScheme(Solo); FlxG.forceNoAntialiasing = !antialiasing; FlxG.autoPause = autoPause; + FlxG.sound.volume = volume; } public static function save() { + volume = FlxG.sound.volume; for(field in Type.getClassFields(Options)) { var obj = Reflect.field(Options, field); if (Reflect.isFunction(obj) || obj is FlxSave) continue; diff --git a/source/funkin/scripting/events/NoteHitEvent.hx b/source/funkin/scripting/events/NoteHitEvent.hx index 858b38c9..7790d2bd 100644 --- a/source/funkin/scripting/events/NoteHitEvent.hx +++ b/source/funkin/scripting/events/NoteHitEvent.hx @@ -14,6 +14,14 @@ class NoteHitEvent extends CancellableEvent { Whenever a miss should be added. **/ public var misses:Bool = true; + /** + Whenever a miss should be added. + **/ + public var countAsCombo:Bool = true; + /** + Whenever ratings should be shown or not. + **/ + public var showRating:Null = null; /** * Note that has been pressed */ @@ -23,7 +31,7 @@ class NoteHitEvent extends CancellableEvent { */ public var character:Character; /** - * Whenever the Character is the player + * Whenever the Character is a player */ public var player:Bool; /** @@ -34,6 +42,14 @@ class NoteHitEvent extends CancellableEvent { * Suffix of the animation. "-alt" for alt notes, "" for normal ones. */ public var animSuffix:String; + /** + * Prefix of the rating sprite path. Defaults to "game/score/" + */ + public var ratingPrefix:String; + /** + * Suffix of the rating sprite path. + */ + public var ratingSuffix:String; /** * Direction of the press (0 = Left, 1 = Down, 2 = Up, 3 = Right) */ @@ -42,15 +58,42 @@ class NoteHitEvent extends CancellableEvent { * Score gained after note press. */ public var score:Int; + /** + * Accuracy gained from pressing this note. From 0 to 1. null means no accuracy is gained. + */ + public var accuracy:Null; /** * The amount of health that'll be gained from pressing that note. If called from `onNoteMiss`, the value will be negative. */ public var healthGain:Float; + /** + * Rating name. Defaults to "sick", "good", "bad" and "shit". Customisable. + */ + public var rating:String = "sick"; + /** + * Scale of ratings. + */ + public var ratingScale:Float = 0.7; + /** + * Whenever antialiasing should be enabled on ratings. + */ + public var ratingAntialiasing:Bool = true; + /** + * Scale of combo numbers. + */ + public var numScale:Float = 0.5; + /** + * Whenever antialiasing should be enabled on combo number. + */ + public var numAntialiasing:Bool = true; /** * Creates a new NoteHitEvent. */ - public function new(note:Note, character:Character, player:Bool, noteType:String, direction:Int, healthGain:Float, unmuteVocals:Bool = true, score:Int = 350, animSuffix:String = "") { + public function new(note:Note, character:Character, player:Bool, noteType:String, + direction:Int, healthGain:Float, unmuteVocals:Bool = true, score:Int = 350, + animSuffix:String = "", rating:String = "sick", accuracy:Null = 1, ratingPrefix:String = "", + ratingSuffix:String = "") { super(); this.note = note; @@ -62,6 +105,11 @@ class NoteHitEvent extends CancellableEvent { this.unmuteVocals = unmuteVocals; this.score = score; this.animSuffix = animSuffix; + this.countAsCombo = !note.isSustainNote && note.mustPress; + this.rating = rating; + this.accuracy = accuracy; + this.ratingPrefix = ratingPrefix; + this.ratingSuffix = ratingSuffix; } /**