From c809edbce35af805ee8c05116d671aecd5b051f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=8D=9A=7ENex?= <87421482+NexIsDumb@users.noreply.github.com> Date: Thu, 8 May 2025 00:31:00 +0200 Subject: [PATCH 01/41] ubuntu latest breaking any % (linux worflow fix) the oddest thing tho isthat ubuntu-latest and ubuntu-24.04 are the same thing rn, last linux build was using 24.04 and was succesful, this time wasnt, not even if i put 24.04; prob github workflows updated some ubuntu components that cause this error ... --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1efcfcfa..cd6f4099 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -7,7 +7,7 @@ jobs: build: name: Linux Build permissions: write-all - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Pulling the source uses: actions/checkout@v2 From f59864d8a4e205d3254eebb4e5a1f042988103f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=8D=9A=7ENex?= <87421482+NexIsDumb@users.noreply.github.com> Date: Thu, 8 May 2025 18:04:42 +0200 Subject: [PATCH 02/41] StoryWeeklist + Week class+ loading weeks fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BIG REWRITE!! a 2 YEARS OLD commit, are we DEADASS for never noticing the way they loaded😭🥀 --- source/funkin/backend/chart/Chart.hx | 38 ++- .../scripting/events/WeekSelectEvent.hx | 2 +- source/funkin/backend/week/Week.hx | 86 +++++++ source/funkin/backend/week/WeekData.hx | 29 +++ source/funkin/game/PlayState.hx | 5 +- source/funkin/menus/FreeplayState.hx | 10 +- source/funkin/menus/StoryMenuState.hx | 222 ++++++------------ 7 files changed, 202 insertions(+), 190 deletions(-) create mode 100644 source/funkin/backend/week/Week.hx create mode 100644 source/funkin/backend/week/WeekData.hx diff --git a/source/funkin/backend/chart/Chart.hx b/source/funkin/backend/chart/Chart.hx index a65f45b7..15f732ca 100644 --- a/source/funkin/backend/chart/Chart.hx +++ b/source/funkin/backend/chart/Chart.hx @@ -87,30 +87,25 @@ class Chart { return data; } - public static function loadChartMeta(songName:String, difficulty:String = "normal", fromMods:Bool = true) { + public static function loadChartMeta(songName:String, difficulty:String = "normal", fromMods:Bool = true):ChartMetaData { var songNameLower = songName.toLowerCase(); var metaPath = Paths.file('songs/${songNameLower}/meta.json'); var metaDiffPath = Paths.file('songs/${songNameLower}/meta-${difficulty.toLowerCase()}.json'); var data:ChartMetaData = null; var fromMods:Bool = fromMods; - for(path in [metaDiffPath, metaPath]) { - if (Assets.exists(path)) { - fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS); - try { - data = Json.parse(Assets.getText(path)); - } catch(e) { - Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR); - } - if (data != null) break; - } + for (path in [metaDiffPath, metaPath]) if (Assets.exists(path)) { + fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS); + try data = Json.parse(Assets.getText(path)) + catch(e) Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR); + if (data != null) break; } - if (data == null) - data = { - name: songName, - bpm: 100 - }; + if (data == null) data = { + name: songName, + bpm: 100 + }; + data.setFieldDefault("name", songName); data.setFieldDefault("beatsPerMeasure", 4); data.setFieldDefault("stepsPerBeat", 4); @@ -165,11 +160,9 @@ class Chart { valid = false; } var data:Dynamic = null; - try { - if (valid) - data = Json.parse(Assets.getText(chartPath)); - } catch(e) { - Logs.trace('Could not parse chart for song ${songName} ($difficulty): ${Std.string(e)}', ERROR, RED); + if (valid) { + try data = Json.parse(Assets.getText(chartPath)) + catch(e) Logs.trace('Could not parse chart for song ${songName} ($difficulty): ${Std.string(e)}', ERROR, RED); } /** @@ -230,8 +223,7 @@ class Chart { return 0; default: var index = chart.noteTypes.indexOf(noteTypeName); - if (index > -1) - return index+1; + if (index > -1) return index + 1; chart.noteTypes.push(noteTypeName); return chart.noteTypes.length; } diff --git a/source/funkin/backend/scripting/events/WeekSelectEvent.hx b/source/funkin/backend/scripting/events/WeekSelectEvent.hx index e255d361..cbb9cab4 100644 --- a/source/funkin/backend/scripting/events/WeekSelectEvent.hx +++ b/source/funkin/backend/scripting/events/WeekSelectEvent.hx @@ -1,6 +1,6 @@ package funkin.backend.scripting.events; -import funkin.menus.StoryMenuState.WeekData; +import funkin.backend.week.WeekData; final class WeekSelectEvent extends CancellableEvent { /** diff --git a/source/funkin/backend/week/Week.hx b/source/funkin/backend/week/Week.hx new file mode 100644 index 00000000..17c58cd0 --- /dev/null +++ b/source/funkin/backend/week/Week.hx @@ -0,0 +1,86 @@ +package funkin.backend.week; + +import flixel.math.FlxPoint; +import funkin.backend.week.WeekData.WeekCharacter; +import funkin.backend.week.WeekData; +import haxe.xml.Access; + +class Week { + public static function loadWeek(weekName:String, loadCharactersData:Bool = true):WeekData { + var week:Access = null; + try week = new Access(Xml.parse(Assets.getText(Paths.xml('weeks/weeks/$weekName'))).firstElement()) + catch(e) Logs.trace('Cannot parse week "$weekName.xml": ${Std.string(e)}', ERROR); + + if (week == null) return null; + if (!week.has.name) { + Logs.trace('Week "${weekName}" has no name attribute', WARNING); + return null; + } + + var weekObj:WeekData = { + xml: week, + name: week.att.name, + id: weekName, + sprite: week.getAtt('sprite').getDefault(weekName), + chars: [null, null, null], + songs: [], + difficulties: ['easy', 'normal', 'hard'] + }; + + var weekName = weekObj.name; + for (k => song in week.nodes.song) { + if (song == null) continue; + try { + var name = song.innerData.trim(); + if (name == "") { + Logs.trace('Song at index ${k} in week $weekName has no name. Skipping...', WARNING); + continue; + } + weekObj.songs.push({ + name: name, + hide: song.getAtt('hide').getDefault('false') == "true", + displayName: song.getAtt('displayName') + }); + } catch(e) { + Logs.trace('Song at index ${k} in week $weekName cannot contain any other XML nodes in its name.', WARNING); + continue; + } + } + + if (weekObj.songs.length <= 0) { + Logs.trace('Week $weekName has no songs.', WARNING); + return null; + } + + var diffNodes = week.nodes.difficulty; + if (diffNodes.length > 0) { + var diffs:Array = [for (e in diffNodes) if (e.has.name) e.att.name]; + if (diffs.length > 0) weekObj.difficulties = diffs; + } + + if (week.has.chars) for (k => e in week.att.chars.split(",")) { + var trim = e.trim(); + weekObj.chars[k] = (trim == "" || e == "none" || e == "null") ? null : (loadCharactersData ? loadWeekCharacter(trim) : {name: trim}); + } + + return weekObj; + } + + public static function loadWeekCharacter(charName:String):WeekCharacter { + var char:Access = null; + try char = new Access(Xml.parse(Assets.getText(Paths.xml('weeks/characters/$charName'))).firstElement()) + catch(e) Logs.trace('Cannot parse character "$charName.xml": ${Std.string(e)}', ERROR); + if (char == null) return null; + + return { + xml: char, + name: charName, + spritePath: Paths.image(char.getAtt('sprite').getDefault('menus/storymenu/characters/${charName}')), + scale: Std.parseFloat(char.getAtt('scale')).getDefault(1), + offset: FlxPoint.get( + Std.parseFloat(char.getAtt('x')).getDefault(0), + Std.parseFloat(char.getAtt('y')).getDefault(0) + ) + }; + } +} \ No newline at end of file diff --git a/source/funkin/backend/week/WeekData.hx b/source/funkin/backend/week/WeekData.hx new file mode 100644 index 00000000..8f51872a --- /dev/null +++ b/source/funkin/backend/week/WeekData.hx @@ -0,0 +1,29 @@ +package funkin.backend.week; + +import flixel.math.FlxPoint; +import haxe.xml.Access; + +typedef WeekData = { + var ?xml:Access; + var name:String; // name SHOULD NOT be used for loading week highscores, its just the name on the right side of the week, remember that next time!! - Nex + var id:String; // id IS instead for saving and loading!! - Nex + var sprite:String; + var chars:Array; + var songs:Array; + var difficulties:Array; +} + +typedef WeekCharacter = { + var ?xml:Access; + var name:String; + var ?spritePath:String; + var ?scale:Float; + var ?offset:FlxPoint; + // var frames:FlxFramesCollection; +} + +typedef WeekSong = { + var name:String; + var hide:Bool; + var ?displayName:String; +} \ No newline at end of file diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 7a57c1ea..c81602c8 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -12,7 +12,7 @@ import funkin.backend.chart.Chart; import funkin.backend.chart.ChartData; import funkin.game.SplashHandler; import funkin.backend.scripting.DummyScript; -import funkin.menus.StoryMenuState.WeekData; +import funkin.backend.week.WeekData; import funkin.backend.FunkinText; import funkin.backend.scripting.Script; import funkin.backend.scripting.ScriptPack; @@ -1961,7 +1961,7 @@ class PlayState extends MusicBeatState */ public static function loadWeek(weekData:WeekData, difficulty:String = "normal") { storyWeek = weekData; - storyPlaylist = [for(e in weekData.songs) e.name]; + storyPlaylist = [for (e in weekData.songs) e.name]; isStoryMode = true; campaignScore = 0; campaignMisses = 0; @@ -1994,7 +1994,6 @@ class PlayState extends MusicBeatState */ public static function __loadSong(name:String, difficulty:String) { PlayState.difficulty = difficulty; - PlayState.SONG = Chart.parse(name, difficulty); PlayState.fromMods = PlayState.SONG.fromMods; } diff --git a/source/funkin/menus/FreeplayState.hx b/source/funkin/menus/FreeplayState.hx index 0542ab17..fc56054a 100644 --- a/source/funkin/menus/FreeplayState.hx +++ b/source/funkin/menus/FreeplayState.hx @@ -439,16 +439,10 @@ class FreeplaySonglist { public function getSongsFromSource(source:funkin.backend.assets.AssetsLibraryList.AssetSource, useTxt:Bool = true) { var path:String = Paths.txt('freeplaySonglist'); - var songsFound:Array = []; - if (useTxt && Paths.assetsTree.existsSpecific(path, "TEXT", source)) { - songsFound = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); - } else { - songsFound = Paths.getFolderDirectories('songs', false, source); - } + var songsFound:Array = useTxt && Paths.assetsTree.existsSpecific(path, "TEXT", source) ? CoolUtil.coolTextFile(path) : Paths.getFolderDirectories('songs', false, source); if (songsFound.length > 0) { - for(s in songsFound) - songs.push(Chart.loadChartMeta(s, "normal", source == MODS)); + for (s in songsFound) songs.push(Chart.loadChartMeta(s, "normal", source == MODS)); return false; } return true; diff --git a/source/funkin/menus/StoryMenuState.hx b/source/funkin/menus/StoryMenuState.hx index 847d921e..65428e07 100644 --- a/source/funkin/menus/StoryMenuState.hx +++ b/source/funkin/menus/StoryMenuState.hx @@ -1,19 +1,21 @@ package funkin.menus; -import funkin.savedata.FunkinSave; -import haxe.io.Path; -import funkin.backend.scripting.events.*; -import flixel.util.FlxTimer; import flixel.math.FlxPoint; +import flixel.text.FlxText; import flixel.tweens.FlxTween; import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import flixel.util.typeLimit.OneOfTwo; import funkin.backend.FunkinText; -import haxe.xml.Access; -import flixel.text.FlxText; +import funkin.backend.scripting.events.*; +import funkin.backend.week.*; +import funkin.savedata.FunkinSave; +import haxe.io.Path; class StoryMenuState extends MusicBeatState { - public var characters:Map = []; + public var characters:Map = []; public var weeks:Array = []; + public var weekList:StoryWeeklist; public var scoreText:FlxText; public var tracklist:FlxText; @@ -84,22 +86,20 @@ class StoryMenuState extends MusicBeatState { tracklist.color = 0xFFE55777; add(weekSprites); - for(e in [blackBar, scoreText, weekTitle, weekBG, tracklist]) { + for (e in [blackBar, scoreText, weekTitle, weekBG, tracklist]) { e.scrollFactor.set(); add(e); } characterSprites = new FlxTypedGroup(); - for(i in 0...3) { - characterSprites.add(new MenuCharacterSprite(i)); - } + for (i in 0...3) characterSprites.add(new MenuCharacterSprite(i)); add(characterSprites); - for(i=>week in weeks) { + for (i=>week in weeks) { var spr:MenuItem = new MenuItem(0, (i * 120) + 480, 'menus/storymenu/weeks/${week.sprite}'); weekSprites.add(spr); - for(e in week.difficulties) { + for (e in week.difficulties) { var le = e.toLowerCase(); if (difficultySprites[le] == null) { var diffSprite = new FlxSprite(leftArrow.x + leftArrow.width, leftArrow.y); @@ -171,11 +171,13 @@ class StoryMenuState extends MusicBeatState { e.targetY = k - curWeek; e.alpha = k == curWeek ? 1.0 : 0.6; } - tracklist.text = 'TRACKS\n\n${[for(e in weeks[curWeek].songs) if (!e.hide) e.name.toUpperCase()].join('\n')}'; + tracklist.text = 'TRACKS\n\n${[for(e in weeks[curWeek].songs) if (!e.hide) e.displayName.getDefault(e.name).toUpperCase()].join('\n')}'; weekTitle.text = weeks[curWeek].name.getDefault(""); - for(i in 0...3) - characterSprites.members[i].changeCharacter(characters[weeks[curWeek].chars[i]]); + for (i in 0...3) { + var char = weeks[curWeek].chars[i]; // will use the characters map in any case since a map is for sure easier to edit for mods, we didnt load characters by default anyways - Nex + characterSprites.members[i].changeCharacter(char == null ? null : characters[char.name]); + } changeDifficulty(0, true); @@ -210,121 +212,25 @@ class StoryMenuState extends MusicBeatState { } public function loadXMLs() { - // CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); - var weeks:Array = []; - if (getWeeksFromSource(weeks, MODS)) - getWeeksFromSource(weeks, SOURCE); - - for(k=>weekName in weeks) { - var week:Access = null; - try { - week = new Access(Xml.parse(Assets.getText(Paths.xml('weeks/weeks/$weekName'))).firstElement()); - } catch(e) { - Logs.trace('Cannot parse week "$weekName.xml": ${Std.string(e)}`', ERROR); - } - - if (week == null) continue; - - if (!week.has.name) { - Logs.trace('Story Menu: Week at index ${k} has no name. Skipping...', WARNING); - continue; - } - var weekObj:WeekData = { - name: week.att.name, - id: weekName, - sprite: week.getAtt('sprite').getDefault(weekName), - chars: [null, null, null], - songs: [], - difficulties: ['easy', 'normal', 'hard'] - }; - - var diffNodes = week.nodes.difficulty; - if (diffNodes.length > 0) { - var diffs:Array = []; - for(e in diffNodes) { - if (e.has.name) diffs.push(e.att.name); - } - if (diffs.length > 0) - weekObj.difficulties = diffs; - } - - if (week.has.chars) { - for(k=>e in week.att.chars.split(",")) { - if (e.trim() == "" || e == "none" || e == "null") - weekObj.chars[k] = null; - else { - addCharacter(weekObj.chars[k] = e.trim()); - } - } - } - for(k2=>song in week.nodes.song) { - if (song == null) continue; - try { - var name = song.innerData.trim(); - if (name == "") { - Logs.trace('Story Menu: Song at index ${k2} in week ${weekObj.name} has no name. Skipping...', WARNING); - continue; - } - weekObj.songs.push({ - name: name, - hide: song.getAtt('hide').getDefault('false') == "true" - }); - } catch(e) { - Logs.trace('Story Menu: Song at index ${k2} in week ${weekObj.name} cannot contain any other XML nodes in its name.', WARNING); - continue; - } - } - if (weekObj.songs.length <= 0) { - Logs.trace('Story Menu: Week ${weekObj.name} has no songs. Skipping...', WARNING); - continue; - } - this.weeks.push(weekObj); - } + weekList = StoryWeeklist.get(true, false); // will only load week files AND NOT characters too (we will load them later only if needed)!! - Nex + weeks = weekList.weeks; + for (week in weeks) for (char in week.chars) if (char != null) + addCharacter(char.name); } - public function addCharacter(charName:String) { - var char:Access = null; - try { - char = new Access(Xml.parse(Assets.getText(Paths.xml('weeks/characters/$charName'))).firstElement()); - } catch(e) { - Logs.trace('Story Menu: Cannot parse character "$charName.xml": ${Std.string(e)}`', ERROR); - } - if (char == null) return; + public function addCharacter(char:OneOfTwo) { + // better to use unsafe casts for going fast - Nex + var charObj:WeekData.WeekCharacter = null; + var charName:String; - if (characters[charName] != null) return; - var charObj:MenuCharacter = { - spritePath: Paths.image(char.getAtt('sprite').getDefault('menus/storymenu/characters/${charName}')), - scale: Std.parseFloat(char.getAtt('scale')).getDefault(1), - xml: char, - offset: FlxPoint.get( - Std.parseFloat(char.getAtt('x')).getDefault(0), - Std.parseFloat(char.getAtt('y')).getDefault(0) - ) - }; - characters[charName] = charObj; - } - - public function getWeeksFromSource(weeks:Array, source:funkin.backend.assets.AssetsLibraryList.AssetSource) { - var path:String = Paths.txt('freeplaySonglist'); - var weeksFound:Array = []; - if (Paths.assetsTree.existsSpecific(path, "TEXT", source)) { - var trim = ""; - weeksFound = CoolUtil.coolTextFile(Paths.txt('weeks/weeks')); - } else { - weeksFound = [for(c in Paths.getFolderContent('data/weeks/weeks/', false, source)) if (Path.extension(c).toLowerCase() == "xml") Path.withoutExtension(c)]; - } - - if (weeksFound.length > 0) { - for(s in weeksFound) - weeks.push(s); - return false; - } - return true; + charName = char is String ? cast char : (charObj = cast char).name; + if (characters[charName] != null) return; // will load only if it can be saved inside the map - Nex + characters[charName] = charObj == null ? Week.loadWeekCharacter(charName) : charObj; } public override function destroy() { super.destroy(); - for(e in characters) + for (e in characters) if (e != null && e.offset != null) e.offset.put(); } @@ -350,28 +256,6 @@ class StoryMenuState extends MusicBeatState { } } -typedef WeekData = { - var name:String; // name SHOULD NOT be used for loading week highscores, its just the name on the right side of the week, remember that next time!! - Nex - var id:String; // id IS instead for saving and loading!! - Nex - var sprite:String; - var chars:Array; - var songs:Array; - var difficulties:Array; -} - -typedef WeekSong = { - var name:String; - var hide:Bool; -} - -typedef MenuCharacter = { - var spritePath:String; - var xml:Access; - var scale:Float; - var offset:FlxPoint; - // var frames:FlxFramesCollection; -} - class MenuCharacterSprite extends FlxSprite { public var character:String; @@ -385,19 +269,16 @@ class MenuCharacterSprite extends FlxSprite antialiasing = true; } - public var oldChar:MenuCharacter = null; + public var oldChar:WeekData.WeekCharacter = null; - public function changeCharacter(data:MenuCharacter) { - visible = (data != null); - if (!visible) - return; + public function changeCharacter(data:WeekData.WeekCharacter) { + visible = (data != null && data.xml != null); + if (!visible) return; if (oldChar != (oldChar = data)) { CoolUtil.loadAnimatedGraphic(this, data.spritePath); - for(e in data.xml.nodes.anim) { - if (e.getAtt("name") == "idle") - animation.remove("idle"); - + for (e in data.xml.nodes.anim) { + if (e.getAtt("name") == "idle") animation.remove("idle"); XMLUtil.addXMLAnimation(this, e); } animation.play("idle"); @@ -410,6 +291,7 @@ class MenuCharacterSprite extends FlxSprite } } } + class MenuItem extends FlxSprite { public var targetY:Float = 0; @@ -451,3 +333,33 @@ class MenuItem extends FlxSprite color = (time % 0.1 > 0.05) ? FlxColor.WHITE : 0xFF33ffff; } } + +class StoryWeeklist { + public var weeks:Array = []; + + public function new() {} + + public function getWeeksFromSource(source:funkin.backend.assets.AssetsLibraryList.AssetSource, useTxt:Bool = true, loadCharactersData:Bool = true) { + var path:String = Paths.txt('weeks/weeks'); + var weeksFound:Array = useTxt && Paths.assetsTree.existsSpecific(path, "TEXT", source) ? CoolUtil.coolTextFile(path) : + [for(c in Paths.getFolderContent('data/weeks/weeks/', false, source)) if (Path.extension(c).toLowerCase() == "xml") Path.withoutExtension(c)]; + + if (weeksFound.length > 0) { + for (w in weeksFound) { + var week = Week.loadWeek(w, loadCharactersData); + if (week != null) weeks.push(week); + } + return false; + } + return true; + } + + public static function get(useTxt:Bool = true, loadCharactersData:Bool = true) { + var weekList = new StoryWeeklist(); + + if (weekList.getWeeksFromSource(MODS, useTxt, loadCharactersData)) + weekList.getWeeksFromSource(SOURCE, useTxt, loadCharactersData); + + return weekList; + } +} \ No newline at end of file From fcfc7950a1669da4d77fd972bdd2077c074e0d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=8D=9A=7ENex?= <87421482+NexIsDumb@users.noreply.github.com> Date: Sun, 11 May 2025 02:26:11 +0200 Subject: [PATCH 03/41] making the endingSong bool actually work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit that variable has been there for 3 years btw😭 --- source/funkin/backend/assets/ModsFolderLibrary.hx | 5 +---- source/funkin/game/PlayState.hx | 1 + source/funkin/menus/StoryMenuState.hx | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/source/funkin/backend/assets/ModsFolderLibrary.hx b/source/funkin/backend/assets/ModsFolderLibrary.hx index ed608bda..0f71db77 100644 --- a/source/funkin/backend/assets/ModsFolderLibrary.hx +++ b/source/funkin/backend/assets/ModsFolderLibrary.hx @@ -26,10 +26,7 @@ class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary { this.folderPath = folderPath; this.libName = libName; this.prefix = 'assets/$libName/'; - if(modName == null) - this.modName = libName; - else - this.modName = modName; + this.modName = modName == null ? libName : modName; super(); } diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index c81602c8..8c8f5f8a 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -1515,6 +1515,7 @@ class PlayState extends MusicBeatState */ public function endSong():Void { + endingSong = true; scripts.call("onSongEnd"); canPause = false; inst.volume = 0; diff --git a/source/funkin/menus/StoryMenuState.hx b/source/funkin/menus/StoryMenuState.hx index 65428e07..915ddaec 100644 --- a/source/funkin/menus/StoryMenuState.hx +++ b/source/funkin/menus/StoryMenuState.hx @@ -272,8 +272,7 @@ class MenuCharacterSprite extends FlxSprite public var oldChar:WeekData.WeekCharacter = null; public function changeCharacter(data:WeekData.WeekCharacter) { - visible = (data != null && data.xml != null); - if (!visible) return; + if (!(visible = (data != null && data.xml != null))) return; if (oldChar != (oldChar = data)) { CoolUtil.loadAnimatedGraphic(this, data.spritePath); @@ -342,7 +341,7 @@ class StoryWeeklist { public function getWeeksFromSource(source:funkin.backend.assets.AssetsLibraryList.AssetSource, useTxt:Bool = true, loadCharactersData:Bool = true) { var path:String = Paths.txt('weeks/weeks'); var weeksFound:Array = useTxt && Paths.assetsTree.existsSpecific(path, "TEXT", source) ? CoolUtil.coolTextFile(path) : - [for(c in Paths.getFolderContent('data/weeks/weeks/', false, source)) if (Path.extension(c).toLowerCase() == "xml") Path.withoutExtension(c)]; + [for (c in Paths.getFolderContent('data/weeks/weeks/', false, source)) if (Path.extension(c).toLowerCase() == "xml") Path.withoutExtension(c)]; if (weeksFound.length > 0) { for (w in weeksFound) { From 137af7fdb6b639f2b7a98d0b803598471f41f40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=8D=9A=7ENex?= <87421482+NexIsDumb@users.noreply.github.com> Date: Mon, 12 May 2025 02:23:44 +0200 Subject: [PATCH 04/41] lil dialogue fix if u had another dialogue starting in the callback, in the new script Dialogue.cutscene would be always null --- source/funkin/game/cutscenes/DialogueCutscene.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/game/cutscenes/DialogueCutscene.hx b/source/funkin/game/cutscenes/DialogueCutscene.hx index b9a7c134..2690396d 100644 --- a/source/funkin/game/cutscenes/DialogueCutscene.hx +++ b/source/funkin/game/cutscenes/DialogueCutscene.hx @@ -197,7 +197,7 @@ class DialogueCutscene extends Cutscene { dialogueScript.destroy(); super.destroy(); - cutscene = null; + if (cutscene == this) cutscene = null; FlxG.cameras.remove(dialogueCamera); } } From e9e36edfde6538a8eaec34b4aea26e2aec364b64 Mon Sep 17 00:00:00 2001 From: Ne_Eo Date: Tue, 13 May 2025 16:28:39 +0200 Subject: [PATCH 05/41] Backdrop Rotation & Zoom + FlxPoint Reflectable FlxBackdrop now has .rotation and .zoom allowing you to rotate and zoom You can now also use the entire FlxPoint api from hscript --- source/funkin/editors/EditorTreeMenu.hx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/funkin/editors/EditorTreeMenu.hx b/source/funkin/editors/EditorTreeMenu.hx index f65cd4bf..1577ad96 100644 --- a/source/funkin/editors/EditorTreeMenu.hx +++ b/source/funkin/editors/EditorTreeMenu.hx @@ -7,6 +7,7 @@ import funkin.options.*; class EditorTreeMenu extends TreeMenu { public var bg:FlxBackdrop; public var bgType:String = "default"; + public var bgMovement:FlxPoint = new FlxPoint(); public override function create() { super.create(); @@ -16,16 +17,16 @@ class EditorTreeMenu extends TreeMenu { bg = new FlxBackdrop(); bg.loadGraphic(Paths.image('editors/bgs/${bgType}')); bg.antialiasing = true; + setBackgroundRotation(-5); add(bg); } + public inline function setBackgroundRotation(rotation:Float) { + bg.rotation = rotation; + bg.velocity.set(85, 0).degrees = bg.rotation; + } + public override function exit() { FlxG.switchState(new MainMenuState()); } - - public override function update(elapsed:Float) { - super.update(elapsed); - bg.x += elapsed * 125; - bg.y += elapsed * 125; - } } \ No newline at end of file From 31042a9039f720ccdadc536eb4442cf69919bdd1 Mon Sep 17 00:00:00 2001 From: Ne_Eo Date: Fri, 16 May 2025 01:00:22 +0200 Subject: [PATCH 06/41] Allow addons in mods folder This allows people to add addons using `mods//addons//` --- source/funkin/backend/system/MainState.hx | 80 ++++++++++++++++++----- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/source/funkin/backend/system/MainState.hx b/source/funkin/backend/system/MainState.hx index a5011d6d..2465a357 100644 --- a/source/funkin/backend/system/MainState.hx +++ b/source/funkin/backend/system/MainState.hx @@ -8,6 +8,13 @@ import funkin.menus.TitleState; import funkin.menus.BetaWarningState; import funkin.backend.chart.EventsData; import flixel.FlxState; +import haxe.io.Path; + +@dox(hide) +typedef AddonInfo = { + var name:String; + var path:String; +} /** * Simple state used for loading the game @@ -32,25 +39,64 @@ class MainState extends FlxState { Paths.assetsTree.reset(); #if MOD_SUPPORT - var _lowPriorityAddons:Array = []; - var _highPriorityAddons:Array = []; - var _noPriorityAddons:Array = []; - if (FileSystem.exists(ModsFolder.addonsPath) && FileSystem.isDirectory(ModsFolder.addonsPath)) { - for(i=>addon in [for(dir in FileSystem.readDirectory(ModsFolder.addonsPath)) if (FileSystem.isDirectory('${ModsFolder.addonsPath}$dir')) dir]) { - if (addon.startsWith("[LOW]")) _lowPriorityAddons.insert(0, addon); - else if (addon.startsWith("[HIGH]")) _highPriorityAddons.insert(0, addon); - else _noPriorityAddons.insert(0, addon); - } - for (addon in _lowPriorityAddons) - Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.addonsPath}$addon', StringTools.ltrim(addon.substr("[LOW]".length)))); - } - if (ModsFolder.currentModFolder != null) - Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.modsPath}${ModsFolder.currentModFolder}', ModsFolder.currentModFolder)); + inline function isDirectory(path:String):Bool + return FileSystem.exists(path) && FileSystem.isDirectory(path); - if (FileSystem.exists(ModsFolder.addonsPath) && FileSystem.isDirectory(ModsFolder.addonsPath)){ - for (addon in _noPriorityAddons) Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.addonsPath}$addon', addon)); - for (addon in _highPriorityAddons) Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.addonsPath}$addon', StringTools.ltrim(addon.substr("[HIGH]".length)))); + inline function ltrim(str:String, prefix:String):String + return str.substr(prefix.length).ltrim(); + + inline function loadLib(path:String, name:String) + Paths.assetsTree.addLibrary(ModsFolder.loadModLib(path, name)); + + var _lowPriorityAddons:Array = []; + var _highPriorityAddons:Array = []; + var _noPriorityAddons:Array = []; + + var addonPaths = [ + ModsFolder.addonsPath, + ( + ModsFolder.currentModFolder != null ? + ModsFolder.modsPath + ModsFolder.currentModFolder + "/addons/" : + null + ) + ]; + + for(path in addonPaths) { + if (path == null) continue; + if (!isDirectory(path)) continue; + + for(addon in FileSystem.readDirectory(path)) { + if(!FileSystem.isDirectory(path + addon)) { + switch(Path.extension(addon).toLowerCase()) { + case 'zip': + addon = Path.withoutExtension(addon); + default: + continue; + } + } + + var data:AddonInfo = { + name: addon, + path: path + addon + }; + + if (addon.startsWith("[LOW]")) _lowPriorityAddons.insert(0, data); + else if (addon.startsWith("[HIGH]")) _highPriorityAddons.insert(0, data); + else _noPriorityAddons.insert(0, data); + } } + + for (addon in _lowPriorityAddons) + loadLib(addon.path, ltrim(addon.name, "[LOW]")); + + if (ModsFolder.currentModFolder != null) + loadLib(ModsFolder.modsPath + ModsFolder.currentModFolder, ModsFolder.currentModFolder); + + for (addon in _noPriorityAddons) + loadLib(addon.path, addon.name); + + for (addon in _highPriorityAddons) + loadLib(addon.path, ltrim(addon.name, "[HIGH]")); #end MusicBeatTransition.script = ""; From 0f96b87eebe9570f22cc0d814077c83b29bc7459 Mon Sep 17 00:00:00 2001 From: Ne_Eo Date: Sun, 25 May 2025 16:20:13 +0200 Subject: [PATCH 07/41] Add FUNDING.yml + try fixing issue with linux --- .github/FUNDING.yml | 3 +++ .github/workflows/linux.yml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..2f5488a9 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +ko_fi: codename_engine diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index cd6f4099..5fcd9c8e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -35,13 +35,13 @@ jobs: - name: Building the game run: | haxelib run lime build linux - - name: Tar files - run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin . + # - name: Tar files + # run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin . - name: Uploading artifact (entire build) uses: actions/upload-artifact@v4 with: name: Codename Engine - path: CodenameEngine.tar.gz + path: export/release/linux/bin/ # - name: Uploading artifact (executable) # uses: actions/upload-artifact@v4 # with: From 2d76ba4e98761617f1705bb4b7153cffe062eb9f Mon Sep 17 00:00:00 2001 From: Frakits <90983918+Frakits@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:03:25 +0300 Subject: [PATCH 08/41] get ready for these powers --- source/funkin/backend/system/Main.hx | 2 ++ source/funkin/backend/system/framerate/CodenameBuildField.hx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/funkin/backend/system/Main.hx b/source/funkin/backend/system/Main.hx index 5795c4a1..5764b569 100644 --- a/source/funkin/backend/system/Main.hx +++ b/source/funkin/backend/system/Main.hx @@ -30,6 +30,8 @@ class Main extends Sprite // make this empty once you guys are done with the project. // good luck /gen <3 @crowplexus public static final releaseCycle:String = "Beta"; + // add a version number in dis shid rn + public static final releaseVersion:String = "v0.0.0-legacy" public static var instance:Main; diff --git a/source/funkin/backend/system/framerate/CodenameBuildField.hx b/source/funkin/backend/system/framerate/CodenameBuildField.hx index 6cfb1b8b..8c0a0b2c 100644 --- a/source/funkin/backend/system/framerate/CodenameBuildField.hx +++ b/source/funkin/backend/system/framerate/CodenameBuildField.hx @@ -11,7 +11,7 @@ class CodenameBuildField extends TextField { defaultTextFormat = Framerate.textFormat; autoSize = LEFT; multiline = wordWrap = false; - text = 'Codename Engine ${Main.releaseCycle}\nCommit ${GitCommitMacro.commitNumber} (${GitCommitMacro.commitHash})'; + text = 'Codename Engine ${Main.releaseCycle}\nVersion ${Main.releaseVersion}'; selectable = false; } } From 8d026c9fc603f168afa8b74f231eb37242195ca0 Mon Sep 17 00:00:00 2001 From: Frakits <90983918+Frakits@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:25:48 +0300 Subject: [PATCH 09/41] =?UTF-8?q?oops=20=F0=9F=98=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/funkin/backend/system/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/backend/system/Main.hx b/source/funkin/backend/system/Main.hx index 5764b569..38fa56ab 100644 --- a/source/funkin/backend/system/Main.hx +++ b/source/funkin/backend/system/Main.hx @@ -31,7 +31,7 @@ class Main extends Sprite // good luck /gen <3 @crowplexus public static final releaseCycle:String = "Beta"; // add a version number in dis shid rn - public static final releaseVersion:String = "v0.0.0-legacy" + public static final releaseVersion:String = "v0.1.0-legacy"; public static var instance:Main; From 2992e010696fcd1e6bcbe6d3164dadefcc584866 Mon Sep 17 00:00:00 2001 From: Frakits <90983918+Frakits@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:52:45 +0300 Subject: [PATCH 10/41] ts pmo icl --- project.xml | 2 +- source/funkin/backend/system/Main.hx | 2 +- source/funkin/menus/MainMenuState.hx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project.xml b/project.xml index 382ed9f6..e32d7c9c 100644 --- a/project.xml +++ b/project.xml @@ -5,7 +5,7 @@ title="Friday Night Funkin' - Codename Engine" main="funkin.backend.system.Main" file="CodenameEngine" packageName="com.yoshman29.codenameengine" package="com.yoshman29.codenameengine" - version="0.1.0" company="Yoshman29" /> + version="v0.1.0-legacy" company="Yoshman29" />