mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-22 23:57:50 -05:00
Merge branch 'rewrite/master' into rank-fixes
This commit is contained in:
commit
c64db9966b
18 changed files with 190 additions and 64 deletions
36
CHANGELOG.md
36
CHANGELOG.md
|
@ -6,31 +6,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [0.4.0] - 2024-05-??
|
## [0.4.0] - 2024-05-??
|
||||||
### Added
|
### Added
|
||||||
- 2 new Erect remixes, Eggnog and Satin Panties. Check them out from
|
- 2 new Erect remixes, Eggnog and Satin Panties. Check them out from the Freeplay menu!
|
||||||
- Improvements to the Freeplay screen, with song difficulty ratings and player rank displays.
|
- Major visual improvements to the Results screen, with additional animations and audio based on your performance.
|
||||||
- Reworked the Results screen, with additional animations and audio based on your performance.
|
- Major visual improvements to the Freeplay screen, with song difficulty ratings and player rank displays.
|
||||||
|
- Freeplay now plays a preview of songs when you hover over them.
|
||||||
- Added a Charter field to the chart format, to allow for crediting the creator of a level's chart.
|
- Added a Charter field to the chart format, to allow for crediting the creator of a level's chart.
|
||||||
- You can see who charted a song from the Pause menu.
|
- You can see who charted a song from the Pause menu.
|
||||||
|
- Added a new Scroll Speed chart event to change the note speed mid-song (thanks )
|
||||||
### Changed
|
### Changed
|
||||||
- Tweaked the charts for several songs:
|
- Tweaked the charts for several songs:
|
||||||
|
- Monster
|
||||||
- Winter Horrorland
|
- Winter Horrorland
|
||||||
- Stress
|
- Stress
|
||||||
- Lit Up
|
- Lit Up
|
||||||
|
- Tutorial (increased the note speed slightly)
|
||||||
|
- Senpai (increased the note speed)
|
||||||
|
- Thorns (increased the note speed slightly)
|
||||||
|
- Favorite songs marked in Freeplay are now stored between sessions.
|
||||||
- Custom note styles are now properly supported for songs; add new notestyles via JSON, then select it for use from the Chart Editor Metadata toolbox. (thanks Keoiki!)
|
- Custom note styles are now properly supported for songs; add new notestyles via JSON, then select it for use from the Chart Editor Metadata toolbox. (thanks Keoiki!)
|
||||||
|
- Improved logic for NoteHitScriptEvents, allowing you to view the hit diff and modify whether a note hit is a combo break (thanks nebulazorua!)
|
||||||
- Health icons now support a Winning frame without requiring a spritesheet, simply include a third frame in the icon file. (thanks gamerbross!)
|
- Health icons now support a Winning frame without requiring a spritesheet, simply include a third frame in the icon file. (thanks gamerbross!)
|
||||||
- Remember that for more complex behaviors such as animations or transitions, you should use an XML file to define each frame.
|
- Remember that for more complex behaviors such as animations or transitions, you should use an XML file to define each frame.
|
||||||
### Fixed
|
### Fixed
|
||||||
|
- Fixed a bug where the game would silently fail to load saves on HTML5
|
||||||
|
- Fixed some bugs with the props on the Story Menu not bopping properly
|
||||||
|
- Additional fixes to the Loading bar on HTML5 (thanks lemz1!)
|
||||||
|
- Fixed several bugs with the TitleState, including missing music when returning from the Main Menu (thanks gamerbross!)
|
||||||
|
- Fixed a camera bug in the Main Menu (thanks richTrash21!)
|
||||||
|
- Fixed a bug where changing difficulties in Story mode wouldn't update the score (thanks sectorA!)
|
||||||
|
- Fixed a crash in Freeplay caused by a level referencing an invalid song (thanks gamerbross!)
|
||||||
- Fixed a bug where pressing the volume keys would stop the Toy commercial (thanks gamerbross!)
|
- Fixed a bug where pressing the volume keys would stop the Toy commercial (thanks gamerbross!)
|
||||||
- Fixed a bug where the Chart Editor would crash when losing (thanks gamerbross!)
|
- Fixed a bug where the Chart Editor Playtest would crash when losing (thanks gamerbross!)
|
||||||
|
- Fixed a bug where hold notes would display improperly in the Chart Editor when downscroll was enabled for gameplay (thanks gamerbross!)
|
||||||
|
- Fixed a bug where hold notes would be positioned wrong on downscroll (thanks MaybeMaru!)
|
||||||
|
- Removed a large number of unused imports to optimize builds (thanks Ethan-makes-music!)
|
||||||
|
- Improved debug logging for unscripted stages (thanks gamerbross!)
|
||||||
- Made improvements to compiling documentation (thanks gedehari!)
|
- Made improvements to compiling documentation (thanks gedehari!)
|
||||||
- Fixed a crash on Linux caused by an old version of hxCodec (thanks Noobz4Life!)
|
- Fixed a crash on Linux caused by an old version of hxCodec (thanks Noobz4Life!)
|
||||||
- Optimized animation handling for characters (thanks richTrash21!)
|
- Optimized animation handling for characters (thanks richTrash21!)
|
||||||
|
- Additional bug fixes and optimizations.
|
||||||
|
|
||||||
## [0.3.3] - 2024-05-14
|
## [0.3.3] - 2024-05-14
|
||||||
### Changed
|
### Changed
|
||||||
- Cleaned up some code in `PlayAnimationSongEvent.hx` (thanks BurgerBalls!)
|
- Cleaned up some code in `PlayAnimationSongEvent.hx` (thanks BurgerBalls!)
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix Web Loading Bar (thanks lemz1!)
|
- Fixes to the Loading bar on HTML5 (thanks lemz1!)
|
||||||
- Don't allow any more inputs when exiting freeplay (thanks gamerbros!)
|
- Don't allow any more inputs when exiting freeplay (thanks gamerbros!)
|
||||||
- Fixed using mouse wheel to scroll on freeplay (thanks JugieNoob!)
|
- Fixed using mouse wheel to scroll on freeplay (thanks JugieNoob!)
|
||||||
- Fixed the reset's of the health icons, score, and notes when re-entering gameplay from gameover (thanks ImCodist!)
|
- Fixed the reset's of the health icons, score, and notes when re-entering gameplay from gameover (thanks ImCodist!)
|
||||||
|
@ -38,11 +58,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Fixed camera stutter once a wipe transition to the Main Menu completes (thanks ImCodist!)
|
- Fixed camera stutter once a wipe transition to the Main Menu completes (thanks ImCodist!)
|
||||||
- Fixed an issue where hold note would be invisible for a single frame (thanks ImCodist!)
|
- Fixed an issue where hold note would be invisible for a single frame (thanks ImCodist!)
|
||||||
- Fix tween accumulation on title screen when pressing Y multiple times (thanks TheGaloXx!)
|
- Fix tween accumulation on title screen when pressing Y multiple times (thanks TheGaloXx!)
|
||||||
- Fix for a game over easter egg so you don't accidentally exit it when viewing
|
|
||||||
- Fix a crash when querying FlxG.state in the crash handler
|
- Fix a crash when querying FlxG.state in the crash handler
|
||||||
|
- Fix for a game over easter egg so you don't accidentally exit it when viewing
|
||||||
- Fix an issue where the Freeplay menu never displays 100% clear
|
- Fix an issue where the Freeplay menu never displays 100% clear
|
||||||
|
- Fix an issue where Weekend 1 Pico attempted to retrieve a missing asset.
|
||||||
|
- Fix an issue where duplicate keybinds would be stoed, potentially causing a crash
|
||||||
- Chart debug key now properly returns you to the previous chart editor session if you were playtesting a chart (thanks nebulazorua!)
|
- Chart debug key now properly returns you to the previous chart editor session if you were playtesting a chart (thanks nebulazorua!)
|
||||||
- Hopefully fixed Freeplay crashes on AMD gpu's
|
- Fix a crash on Freeplay found on AMD graphics cards
|
||||||
|
|
||||||
## [0.3.2] - 2024-05-03
|
## [0.3.2] - 2024-05-03
|
||||||
### Added
|
### Added
|
||||||
|
|
2
assets
2
assets
|
@ -1 +1 @@
|
||||||
Subproject commit ad8a0a28addb3153c01bca2f8a2fdea05c5ac9ea
|
Subproject commit d9ea5ebe5e4db8584a8b1e1e16820b4d1527794c
|
|
@ -219,9 +219,9 @@ class InitState extends FlxState
|
||||||
FlxG.switchState(() -> new funkin.play.ResultState(
|
FlxG.switchState(() -> new funkin.play.ResultState(
|
||||||
{
|
{
|
||||||
storyMode: false,
|
storyMode: false,
|
||||||
title: "CUM SONG",
|
title: "Cum Song Erect by Kawai Sprite",
|
||||||
songId: "cum",
|
songId: "cum",
|
||||||
difficultyId: "hard",
|
difficultyId: "nightmare",
|
||||||
isNewHighscore: true,
|
isNewHighscore: true,
|
||||||
scoreData:
|
scoreData:
|
||||||
{
|
{
|
||||||
|
|
|
@ -377,7 +377,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||||
FlxG.sound.music = partialMusic;
|
FlxG.sound.music = partialMusic;
|
||||||
FlxG.sound.list.remove(FlxG.sound.music);
|
FlxG.sound.list.remove(FlxG.sound.music);
|
||||||
|
|
||||||
if (params.onLoad != null) params.onLoad();
|
if (FlxG.sound.music != null && params.onLoad != null) params.onLoad();
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -488,6 +488,12 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||||
|
|
||||||
var soundRequest = FlxPartialSound.partialLoadFromFile(path, start, end);
|
var soundRequest = FlxPartialSound.partialLoadFromFile(path, start, end);
|
||||||
|
|
||||||
|
if (soundRequest == null)
|
||||||
|
{
|
||||||
|
promise.complete(null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
promise.future.onError(function(e) {
|
promise.future.onError(function(e) {
|
||||||
soundRequest.error("Sound loading was errored or cancelled");
|
soundRequest.error("Sound loading was errored or cancelled");
|
||||||
});
|
});
|
||||||
|
@ -496,6 +502,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||||
var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad);
|
var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad);
|
||||||
promise.complete(snd);
|
promise.complete(snd);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ class SongMetadata implements ICloneable<SongMetadata>
|
||||||
@:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY)
|
@:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY)
|
||||||
public var generatedBy:String;
|
public var generatedBy:String;
|
||||||
|
|
||||||
|
@:optional
|
||||||
|
@:default(funkin.data.song.SongData.SongTimeFormat.MILLISECONDS)
|
||||||
public var timeFormat:SongTimeFormat;
|
public var timeFormat:SongTimeFormat;
|
||||||
|
|
||||||
public var timeChanges:Array<SongTimeChange>;
|
public var timeChanges:Array<SongTimeChange>;
|
||||||
|
@ -115,14 +117,23 @@ class SongMetadata implements ICloneable<SongMetadata>
|
||||||
*/
|
*/
|
||||||
public function serialize(pretty:Bool = true):String
|
public function serialize(pretty:Bool = true):String
|
||||||
{
|
{
|
||||||
|
// Update generatedBy and version before writing.
|
||||||
|
updateVersionToLatest();
|
||||||
|
|
||||||
var ignoreNullOptionals = true;
|
var ignoreNullOptionals = true;
|
||||||
var writer = new json2object.JsonWriter<SongMetadata>(ignoreNullOptionals);
|
var writer = new json2object.JsonWriter<SongMetadata>(ignoreNullOptionals);
|
||||||
// I believe @:jignored should be iggnored by the writer?
|
// I believe @:jignored should be ignored by the writer?
|
||||||
// var output = this.clone();
|
// var output = this.clone();
|
||||||
// output.variation = null; // Not sure how to make a field optional on the reader and ignored on the writer.
|
// output.variation = null; // Not sure how to make a field optional on the reader and ignored on the writer.
|
||||||
return writer.write(this, pretty ? ' ' : null);
|
return writer.write(this, pretty ? ' ' : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateVersionToLatest():Void
|
||||||
|
{
|
||||||
|
this.version = SongRegistry.SONG_METADATA_VERSION;
|
||||||
|
this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces a string representation suitable for debugging.
|
* Produces a string representation suitable for debugging.
|
||||||
*/
|
*/
|
||||||
|
@ -371,6 +382,12 @@ class SongMusicData implements ICloneable<SongMusicData>
|
||||||
this.variation = variation == null ? Constants.DEFAULT_VARIATION : variation;
|
this.variation = variation == null ? Constants.DEFAULT_VARIATION : variation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateVersionToLatest():Void
|
||||||
|
{
|
||||||
|
this.version = SongRegistry.SONG_MUSIC_DATA_VERSION;
|
||||||
|
this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY;
|
||||||
|
}
|
||||||
|
|
||||||
public function clone():SongMusicData
|
public function clone():SongMusicData
|
||||||
{
|
{
|
||||||
var result:SongMusicData = new SongMusicData(this.songName, this.artist, this.variation);
|
var result:SongMusicData = new SongMusicData(this.songName, this.artist, this.variation);
|
||||||
|
@ -603,11 +620,20 @@ class SongChartData implements ICloneable<SongChartData>
|
||||||
*/
|
*/
|
||||||
public function serialize(pretty:Bool = true):String
|
public function serialize(pretty:Bool = true):String
|
||||||
{
|
{
|
||||||
|
// Update generatedBy and version before writing.
|
||||||
|
updateVersionToLatest();
|
||||||
|
|
||||||
var ignoreNullOptionals = true;
|
var ignoreNullOptionals = true;
|
||||||
var writer = new json2object.JsonWriter<SongChartData>(ignoreNullOptionals);
|
var writer = new json2object.JsonWriter<SongChartData>(ignoreNullOptionals);
|
||||||
return writer.write(this, pretty ? ' ' : null);
|
return writer.write(this, pretty ? ' ' : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateVersionToLatest():Void
|
||||||
|
{
|
||||||
|
this.version = SongRegistry.SONG_CHART_DATA_VERSION;
|
||||||
|
this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY;
|
||||||
|
}
|
||||||
|
|
||||||
public function clone():SongChartData
|
public function clone():SongChartData
|
||||||
{
|
{
|
||||||
// We have to manually perform the deep clone here because Map.deepClone() doesn't work.
|
// We have to manually perform the deep clone here because Map.deepClone() doesn't work.
|
||||||
|
|
|
@ -61,10 +61,18 @@ class ChartManifestData
|
||||||
*/
|
*/
|
||||||
public function serialize(pretty:Bool = true):String
|
public function serialize(pretty:Bool = true):String
|
||||||
{
|
{
|
||||||
|
// Update generatedBy and version before writing.
|
||||||
|
updateVersionToLatest();
|
||||||
|
|
||||||
var writer = new json2object.JsonWriter<ChartManifestData>();
|
var writer = new json2object.JsonWriter<ChartManifestData>();
|
||||||
return writer.write(this, pretty ? ' ' : null);
|
return writer.write(this, pretty ? ' ' : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateVersionToLatest():Void
|
||||||
|
{
|
||||||
|
this.version = CHART_MANIFEST_DATA_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
public static function deserialize(contents:String):Null<ChartManifestData>
|
public static function deserialize(contents:String):Null<ChartManifestData>
|
||||||
{
|
{
|
||||||
var parser = new json2object.JsonParser<ChartManifestData>();
|
var parser = new json2object.JsonParser<ChartManifestData>();
|
||||||
|
|
|
@ -65,7 +65,7 @@ class FNFLegacyImporter
|
||||||
|
|
||||||
songMetadata.timeChanges = rebuildTimeChanges(songData);
|
songMetadata.timeChanges = rebuildTimeChanges(songData);
|
||||||
|
|
||||||
songMetadata.playData.characters = new SongCharacterData(songData?.song?.player1 ?? 'bf', 'gf', songData?.song?.player2 ?? 'dad', 'mom');
|
songMetadata.playData.characters = new SongCharacterData(songData?.song?.player1 ?? 'bf', 'gf', songData?.song?.player2 ?? 'dad');
|
||||||
|
|
||||||
return songMetadata;
|
return songMetadata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,17 @@ class StageData
|
||||||
*/
|
*/
|
||||||
public function serialize(pretty:Bool = true):String
|
public function serialize(pretty:Bool = true):String
|
||||||
{
|
{
|
||||||
|
// Update generatedBy and version before writing.
|
||||||
|
updateVersionToLatest();
|
||||||
|
|
||||||
var writer = new json2object.JsonWriter<StageData>();
|
var writer = new json2object.JsonWriter<StageData>();
|
||||||
return writer.write(this, pretty ? ' ' : null);
|
return writer.write(this, pretty ? ' ' : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateVersionToLatest():Void
|
||||||
|
{
|
||||||
|
this.version = StageRegistry.STAGE_DATA_VERSION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef StageDataCharacters =
|
typedef StageDataCharacters =
|
||||||
|
|
|
@ -3144,7 +3144,7 @@ class PlayState extends MusicBeatSubState
|
||||||
},
|
},
|
||||||
isNewHighscore: isNewHighscore
|
isNewHighscore: isNewHighscore
|
||||||
});
|
});
|
||||||
res.camera = camHUD;
|
this.persistentDraw = false;
|
||||||
openSubState(res);
|
openSubState(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,10 @@ import funkin.ui.freeplay.FreeplayScore;
|
||||||
import flixel.text.FlxText;
|
import flixel.text.FlxText;
|
||||||
import flixel.util.FlxColor;
|
import flixel.util.FlxColor;
|
||||||
import flixel.tweens.FlxEase;
|
import flixel.tweens.FlxEase;
|
||||||
|
import funkin.graphics.FunkinCamera;
|
||||||
import funkin.ui.freeplay.FreeplayState;
|
import funkin.ui.freeplay.FreeplayState;
|
||||||
import flixel.tweens.FlxTween;
|
import flixel.tweens.FlxTween;
|
||||||
|
import flixel.addons.display.FlxBackdrop;
|
||||||
import funkin.audio.FunkinSound;
|
import funkin.audio.FunkinSound;
|
||||||
import flixel.util.FlxGradient;
|
import flixel.util.FlxGradient;
|
||||||
import flixel.util.FlxTimer;
|
import flixel.util.FlxTimer;
|
||||||
|
@ -60,6 +62,9 @@ class ResultState extends MusicBeatSubState
|
||||||
var bfShit:Null<FlxAtlasSprite> = null;
|
var bfShit:Null<FlxAtlasSprite> = null;
|
||||||
|
|
||||||
var rankBg:FunkinSprite;
|
var rankBg:FunkinSprite;
|
||||||
|
final cameraBG:FunkinCamera;
|
||||||
|
final cameraScroll:FunkinCamera;
|
||||||
|
final cameraEverything:FunkinCamera;
|
||||||
|
|
||||||
public function new(params:ResultsStateParams)
|
public function new(params:ResultsStateParams)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +74,10 @@ class ResultState extends MusicBeatSubState
|
||||||
|
|
||||||
rank = Scoring.calculateRank(params.scoreData) ?? SHIT;
|
rank = Scoring.calculateRank(params.scoreData) ?? SHIT;
|
||||||
|
|
||||||
|
cameraBG = new FunkinCamera('resultsBG', 0, 0, FlxG.width, FlxG.height);
|
||||||
|
cameraScroll = new FunkinCamera('resultsScroll', 0, 0, FlxG.width, FlxG.height);
|
||||||
|
cameraEverything = new FunkinCamera('resultsEverything', 0, 0, FlxG.width, FlxG.height);
|
||||||
|
|
||||||
// We build a lot of this stuff in the constructor, then place it in create().
|
// We build a lot of this stuff in the constructor, then place it in create().
|
||||||
// This prevents having to do `null` checks everywhere.
|
// This prevents having to do `null` checks everywhere.
|
||||||
|
|
||||||
|
@ -105,17 +114,33 @@ class ResultState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
if (FlxG.sound.music != null) FlxG.sound.music.stop();
|
if (FlxG.sound.music != null) FlxG.sound.music.stop();
|
||||||
|
|
||||||
|
// We need multiple cameras so we can put one at an angle.
|
||||||
|
cameraScroll.angle = -3.8;
|
||||||
|
|
||||||
|
cameraBG.bgColor = FlxColor.MAGENTA;
|
||||||
|
cameraScroll.bgColor = FlxColor.TRANSPARENT;
|
||||||
|
cameraEverything.bgColor = FlxColor.TRANSPARENT;
|
||||||
|
|
||||||
|
FlxG.cameras.add(cameraBG, false);
|
||||||
|
FlxG.cameras.add(cameraScroll, false);
|
||||||
|
FlxG.cameras.add(cameraEverything, false);
|
||||||
|
|
||||||
|
FlxG.cameras.setDefaultDrawTarget(cameraEverything, true);
|
||||||
|
this.camera = cameraEverything;
|
||||||
|
|
||||||
// Reset the camera zoom on the results screen.
|
// Reset the camera zoom on the results screen.
|
||||||
FlxG.camera.zoom = 1.0;
|
FlxG.camera.zoom = 1.0;
|
||||||
|
|
||||||
var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90);
|
var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90);
|
||||||
bg.scrollFactor.set();
|
bg.scrollFactor.set();
|
||||||
bg.zIndex = 10;
|
bg.zIndex = 10;
|
||||||
|
bg.cameras = [cameraBG];
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
bgFlash.scrollFactor.set();
|
bgFlash.scrollFactor.set();
|
||||||
bgFlash.visible = false;
|
bgFlash.visible = false;
|
||||||
bgFlash.zIndex = 20;
|
bgFlash.zIndex = 20;
|
||||||
|
bgFlash.cameras = [cameraBG];
|
||||||
add(bgFlash);
|
add(bgFlash);
|
||||||
|
|
||||||
// The sound system which falls into place behind the score text. Plays every time!
|
// The sound system which falls into place behind the score text. Plays every time!
|
||||||
|
@ -465,16 +490,27 @@ class ResultState extends MusicBeatSubState
|
||||||
|
|
||||||
function displayRankText():Void
|
function displayRankText():Void
|
||||||
{
|
{
|
||||||
var rankTextVert:FunkinSprite = FunkinSprite.create(FlxG.width - 64, 100, rank.getVerTextAsset());
|
var rankTextVert:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getVerTextAsset()), Y, 0, 30);
|
||||||
rankTextVert.zIndex = 2000;
|
rankTextVert.x = FlxG.width - 64;
|
||||||
|
rankTextVert.y = 100;
|
||||||
|
rankTextVert.zIndex = 990;
|
||||||
add(rankTextVert);
|
add(rankTextVert);
|
||||||
|
|
||||||
|
// Scrolling.
|
||||||
|
rankTextVert.velocity.y = -50;
|
||||||
|
|
||||||
for (i in 0...10)
|
for (i in 0...10)
|
||||||
{
|
{
|
||||||
var rankTextBack:FunkinSprite = FunkinSprite.create(FlxG.width / 2 - 80, 50, rank.getHorTextAsset());
|
var rankTextBack:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getHorTextAsset()), X, 10, 0);
|
||||||
rankTextBack.y += (rankTextBack.height * i / 2) + 10;
|
rankTextBack.x = FlxG.width / 2 - 320;
|
||||||
|
rankTextBack.y = 50 + (150 * i / 2) + 10;
|
||||||
|
// rankTextBack.angle = -3.8;
|
||||||
rankTextBack.zIndex = 100;
|
rankTextBack.zIndex = 100;
|
||||||
|
rankTextBack.cameras = [cameraScroll];
|
||||||
add(rankTextBack);
|
add(rankTextBack);
|
||||||
|
|
||||||
|
// Scrolling.
|
||||||
|
rankTextBack.velocity.x = (i % 2 == 0) ? -10.0 : 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
|
@ -351,6 +351,9 @@ class Scoring
|
||||||
{
|
{
|
||||||
if (scoreData?.tallies.totalNotes == 0 || scoreData == null) return null;
|
if (scoreData?.tallies.totalNotes == 0 || scoreData == null) return null;
|
||||||
|
|
||||||
|
// we can return null here, meaning that the player hasn't actually played and finished the song (thus has no data)
|
||||||
|
if (scoreData.tallies.totalNotes == 0) return null;
|
||||||
|
|
||||||
// Perfect (Platinum) is a Sick Full Clear
|
// Perfect (Platinum) is a Sick Full Clear
|
||||||
var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes;
|
var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes;
|
||||||
if (isPerfectGold) return ScoringRank.PERFECT_GOLD;
|
if (isPerfectGold) return ScoringRank.PERFECT_GOLD;
|
||||||
|
|
|
@ -384,17 +384,34 @@ class ChartEditorImportExportHandler
|
||||||
if (variationId == '')
|
if (variationId == '')
|
||||||
{
|
{
|
||||||
var variationMetadata:Null<SongMetadata> = state.songMetadata.get(variation);
|
var variationMetadata:Null<SongMetadata> = state.songMetadata.get(variation);
|
||||||
if (variationMetadata != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata.json', variationMetadata.serialize()));
|
if (variationMetadata != null)
|
||||||
|
{
|
||||||
|
variationMetadata.version = funkin.data.song.SongRegistry.SONG_METADATA_VERSION;
|
||||||
|
variationMetadata.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY;
|
||||||
|
zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata.json', variationMetadata.serialize()));
|
||||||
|
}
|
||||||
var variationChart:Null<SongChartData> = state.songChartData.get(variation);
|
var variationChart:Null<SongChartData> = state.songChartData.get(variation);
|
||||||
if (variationChart != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart.json', variationChart.serialize()));
|
if (variationChart != null)
|
||||||
|
{
|
||||||
|
variationChart.version = funkin.data.song.SongRegistry.SONG_CHART_DATA_VERSION;
|
||||||
|
variationChart.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY;
|
||||||
|
zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart.json', variationChart.serialize()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var variationMetadata:Null<SongMetadata> = state.songMetadata.get(variation);
|
var variationMetadata:Null<SongMetadata> = state.songMetadata.get(variation);
|
||||||
if (variationMetadata != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata-$variationId.json',
|
if (variationMetadata != null)
|
||||||
variationMetadata.serialize()));
|
{
|
||||||
|
zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata-$variationId.json', variationMetadata.serialize()));
|
||||||
|
}
|
||||||
var variationChart:Null<SongChartData> = state.songChartData.get(variation);
|
var variationChart:Null<SongChartData> = state.songChartData.get(variation);
|
||||||
if (variationChart != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', variationChart.serialize()));
|
if (variationChart != null)
|
||||||
|
{
|
||||||
|
variationChart.version = funkin.data.song.SongRegistry.SONG_CHART_DATA_VERSION;
|
||||||
|
variationChart.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY;
|
||||||
|
zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', variationChart.serialize()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the audio preview, the duration of the fade-out effect.
|
* For the audio preview, the duration of the fade-out effect.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public static final FADE_OUT_DURATION:Float = 0.25;
|
public static final FADE_OUT_DURATION:Float = 0.25;
|
||||||
|
|
||||||
|
@ -733,12 +734,6 @@ class FreeplayState extends MusicBeatSubState
|
||||||
// If curSelected is 0, the result will be null and fall back to the rememberedSongId.
|
// If curSelected is 0, the result will be null and fall back to the rememberedSongId.
|
||||||
rememberedSongId = grpCapsules.members[curSelected]?.songData?.songId ?? rememberedSongId;
|
rememberedSongId = grpCapsules.members[curSelected]?.songData?.songId ?? rememberedSongId;
|
||||||
|
|
||||||
if (fromResultsParams != null)
|
|
||||||
{
|
|
||||||
rememberedSongId = fromResultsParams.songId;
|
|
||||||
rememberedDifficulty = fromResultsParams.difficultyId;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cap in grpCapsules.members)
|
for (cap in grpCapsules.members)
|
||||||
{
|
{
|
||||||
cap.songText.resetText();
|
cap.songText.resetText();
|
||||||
|
@ -853,10 +848,18 @@ class FreeplayState extends MusicBeatSubState
|
||||||
busy = true;
|
busy = true;
|
||||||
// grpCapsules.members[curSelected].forcePosition();
|
// grpCapsules.members[curSelected].forcePosition();
|
||||||
|
|
||||||
|
if (fromResults != null)
|
||||||
|
{
|
||||||
|
rememberedSongId = fromResults.songId;
|
||||||
|
rememberedDifficulty = fromResults.difficultyId;
|
||||||
|
changeSelection();
|
||||||
|
changeDiff();
|
||||||
|
}
|
||||||
|
|
||||||
dj.fistPump();
|
dj.fistPump();
|
||||||
// rankCamera.fade(FlxColor.BLACK, 0.5, true);
|
// rankCamera.fade(FlxColor.BLACK, 0.5, true);
|
||||||
rankCamera.fade(0xFF000000, 0.5, true, null, true);
|
rankCamera.fade(0xFF000000, 0.5, true, null, true);
|
||||||
FlxG.sound.music.volume = 0;
|
if (FlxG.sound.music != null) FlxG.sound.music.volume = 0;
|
||||||
rankBg.alpha = 1;
|
rankBg.alpha = 1;
|
||||||
|
|
||||||
if (fromResults?.oldRank != null)
|
if (fromResults?.oldRank != null)
|
||||||
|
@ -1842,11 +1845,8 @@ class FreeplayState extends MusicBeatSubState
|
||||||
FlxG.sound.music.fadeIn(2, 0, 0.8);
|
FlxG.sound.music.fadeIn(2, 0, 0.8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (!prepForNewRank)
|
|
||||||
{
|
{
|
||||||
var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : "";
|
var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : "";
|
||||||
// TODO: Stream the instrumental of the selected song?
|
|
||||||
FunkinSound.playMusic(daSongCapsule.songData.songId,
|
FunkinSound.playMusic(daSongCapsule.songData.songId,
|
||||||
{
|
{
|
||||||
startingVolume: 0.0,
|
startingVolume: 0.0,
|
||||||
|
@ -1857,15 +1857,14 @@ class FreeplayState extends MusicBeatSubState
|
||||||
partialParams:
|
partialParams:
|
||||||
{
|
{
|
||||||
loadPartial: true,
|
loadPartial: true,
|
||||||
start: 0,
|
start: 0.05,
|
||||||
end: 0.1
|
end: 0.25
|
||||||
},
|
},
|
||||||
onLoad: function() {
|
onLoad: function() {
|
||||||
FlxG.sound.music.fadeIn(2, 0, 0.4);
|
FlxG.sound.music.fadeIn(2, 0, 0.4);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
grpCapsules.members[curSelected].selected = true;
|
grpCapsules.members[curSelected].selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,8 +279,6 @@ class SongMenuItem extends FlxSpriteGroup
|
||||||
|
|
||||||
function updateBPM(newBPM:Int):Void
|
function updateBPM(newBPM:Int):Void
|
||||||
{
|
{
|
||||||
trace(newBPM);
|
|
||||||
|
|
||||||
var shiftX:Float = 191;
|
var shiftX:Float = 191;
|
||||||
var tempShift:Float = 0;
|
var tempShift:Float = 0;
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ class TitleState extends MusicBeatState
|
||||||
|
|
||||||
persistentUpdate = true;
|
persistentUpdate = true;
|
||||||
|
|
||||||
var bg:FunkinSprite = new FunkinSprite().makeSolidColor(FlxG.width, FlxG.height, FlxColor.BLACK);
|
var bg:FunkinSprite = new FunkinSprite(-1).makeSolidColor(FlxG.width + 2, FlxG.height, FlxColor.BLACK);
|
||||||
bg.screenCenter();
|
bg.screenCenter();
|
||||||
add(bg);
|
add(bg);
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,8 @@ class FunkinPreloader extends FlxBasePreloader
|
||||||
// We can't even call trace() yet, until Flixel loads.
|
// We can't even call trace() yet, until Flixel loads.
|
||||||
trace('Initializing custom preloader...');
|
trace('Initializing custom preloader...');
|
||||||
|
|
||||||
|
funkin.util.CLIUtil.resetWorkingDir();
|
||||||
|
|
||||||
this.siteLockTitleText = Constants.SITE_LOCK_TITLE;
|
this.siteLockTitleText = Constants.SITE_LOCK_TITLE;
|
||||||
this.siteLockBodyText = Constants.SITE_LOCK_DESC;
|
this.siteLockBodyText = Constants.SITE_LOCK_DESC;
|
||||||
}
|
}
|
||||||
|
|
|
@ -467,7 +467,7 @@ class Constants
|
||||||
// % Hit
|
// % Hit
|
||||||
public static final RANK_PERFECT_THRESHOLD:Float = 1.00;
|
public static final RANK_PERFECT_THRESHOLD:Float = 1.00;
|
||||||
public static final RANK_EXCELLENT_THRESHOLD:Float = 0.90;
|
public static final RANK_EXCELLENT_THRESHOLD:Float = 0.90;
|
||||||
public static final RANK_GREAT_THRESHOLD:Float = 0.75;
|
public static final RANK_GREAT_THRESHOLD:Float = 0.80;
|
||||||
public static final RANK_GOOD_THRESHOLD:Float = 0.60;
|
public static final RANK_GOOD_THRESHOLD:Float = 0.60;
|
||||||
|
|
||||||
// public static final RANK_SHIT_THRESHOLD:Float = 0.00;
|
// public static final RANK_SHIT_THRESHOLD:Float = 0.00;
|
||||||
|
|
Loading…
Reference in a new issue