The actual code for custom freeplay music LOL

This commit is contained in:
EliteMasterEric 2024-09-03 21:14:57 -04:00
parent 2f59363432
commit 36505f75c1
7 changed files with 108 additions and 40 deletions

View file

@ -4,14 +4,28 @@ All notable changes will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.5.0] - 2024-08-?? ## [0.5.0] - 2024-09-12
### Added ### Added
- Added a new Character Select screen to switch between playable characters in Freeplay - Added a new Character Select screen to switch between playable characters in Freeplay
- Modding isn't 100% there but we're working on it! - Modding isn't 100% there but we're working on it!
- Added Pico as a playable character! Unlock him by completing Weekend 1 (if you haven't already done that) - Added Pico as a playable character! Unlock him by completing Weekend 1 (if you haven't already done that)
- The songs from Weekend 1 have moved; you must now switch to Pico in Freeplay to access them - The songs from Weekend 1 have moved; you must now switch to Pico in Freeplay to access them
- Added ## new Pico remixes! Access them by selecting Pico from in the Character Select screen - Added 10 new Pico remixes! Access them by selecting Pico from in the Character Select screen
- Bopeebo (Pico Mix)
- Fresh (Pico Mix)
- DadBattle (Pico Mix)
- Spookeez (Pico Mix)
- South (Pico Mix)
- Philly Nice (Pico Mix)
- Blammed (Pico Mix)
- Eggnog (Pico Mix)
- Ugh (Pico Mix)
- Guns (Pico Mix)
- Added 1 new Boyfriend remix! Access it by selecting Pico from in the Character Select screen
- Darnell (BF Mix)
- Added 2 new Erect remixes! Access them by switching difficulty on the song - Added 2 new Erect remixes! Access them by switching difficulty on the song
- Cocoa Erect
- Ugh Erect
- Implemented support for a new Instrumental Selector in Freeplay - Implemented support for a new Instrumental Selector in Freeplay
- Beating a Pico remix lets you use that instrumental when playing as Boyfriend - Beating a Pico remix lets you use that instrumental when playing as Boyfriend
- Added the first batch of Erect Stages! These graphical overhauls of the original stages will be used when playing Erect remixes and Pico remixes - Added the first batch of Erect Stages! These graphical overhauls of the original stages will be used when playing Erect remixes and Pico remixes

38
source/funkin/Assets.hx Normal file
View file

@ -0,0 +1,38 @@
package funkin;
/**
* A wrapper around `openfl.utils.Assets` which disallows access to the harmful functions.
* Later we'll add Funkin-specific caching to this.
*/
class Assets
{
public static function getText(path:String):String
{
return openfl.utils.Assets.getText(path);
}
public static function getMusic(path:String):openfl.media.Sound
{
return openfl.utils.Assets.getMusic(path);
}
public static function getBitmapData(path:String):openfl.display.BitmapData
{
return openfl.utils.Assets.getBitmapData(path);
}
public static function getBytes(path:String):haxe.io.Bytes
{
return openfl.utils.Assets.getBytes(path);
}
public static function exists(path:String, ?type:openfl.utils.AssetType):Bool
{
return openfl.utils.Assets.exists(path, type);
}
public static function list(type:openfl.utils.AssetType):Array<String>
{
return openfl.utils.Assets.list(type);
}
}

View file

@ -253,6 +253,8 @@ class PlayerCharSelectData
typedef PlayerResultsData = typedef PlayerResultsData =
{ {
var music:PlayerResultsMusicData;
var perfect:Array<PlayerResultsAnimationData>; var perfect:Array<PlayerResultsAnimationData>;
var excellent:Array<PlayerResultsAnimationData>; var excellent:Array<PlayerResultsAnimationData>;
var great:Array<PlayerResultsAnimationData>; var great:Array<PlayerResultsAnimationData>;
@ -260,6 +262,27 @@ typedef PlayerResultsData =
var loss:Array<PlayerResultsAnimationData>; var loss:Array<PlayerResultsAnimationData>;
}; };
typedef PlayerResultsMusicData =
{
@:optional
var PERFECT_GOLD:String;
@:optional
var PERFECT:String;
@:optional
var EXCELLENT:String;
@:optional
var GREAT:String;
@:optional
var GOOD:String;
@:optional
var SHIT:String;
}
typedef PlayerResultsAnimationData = typedef PlayerResultsAnimationData =
{ {
/** /**

View file

@ -404,12 +404,12 @@ class ResultState extends MusicBeatSubState
// } // }
new FlxTimer().start(rank.getMusicDelay(), _ -> { new FlxTimer().start(rank.getMusicDelay(), _ -> {
if (rank.hasMusicIntro()) var introMusic:String = Paths.music(getMusicPath(playerCharacter, rank) + '/' + getMusicPath(playerCharacter, rank) + '-intro');
if (Assets.exists(introMusic))
{ {
// Play the intro music. // Play the intro music.
var introMusic:String = Paths.music(rank.getMusicPath() + '/' + rank.getMusicPath() + '-intro');
FunkinSound.load(introMusic, 1.0, false, true, true, () -> { FunkinSound.load(introMusic, 1.0, false, true, true, () -> {
FunkinSound.playMusic(rank.getMusicPath(), FunkinSound.playMusic(getMusicPath(playerCharacter, rank),
{ {
startingVolume: 1.0, startingVolume: 1.0,
overrideExisting: true, overrideExisting: true,
@ -420,7 +420,7 @@ class ResultState extends MusicBeatSubState
} }
else else
{ {
FunkinSound.playMusic(rank.getMusicPath(), FunkinSound.playMusic(getMusicPath(playerCharacter, rank),
{ {
startingVolume: 1.0, startingVolume: 1.0,
overrideExisting: true, overrideExisting: true,
@ -441,6 +441,11 @@ class ResultState extends MusicBeatSubState
super.create(); super.create();
} }
function getMusicPath(playerCharacter:Null<PlayableCharacter>, rank:ScoringRank):String
{
return playerCharacter?.getResultsMusicPath(rank) ?? 'resultsNORMAL';
}
var rankTallyTimer:Null<FlxTimer> = null; var rankTallyTimer:Null<FlxTimer> = null;
var clearPercentTarget:Int = 100; var clearPercentTarget:Int = 100;
var clearPercentLerp:Int = 0; var clearPercentLerp:Int = 0;

View file

@ -556,40 +556,6 @@ enum abstract ScoringRank(String)
} }
} }
public function getMusicPath():String
{
switch (abstract)
{
case PERFECT_GOLD:
return 'resultsPERFECT';
case PERFECT:
return 'resultsPERFECT';
case EXCELLENT:
return 'resultsEXCELLENT';
case GREAT:
return 'resultsNORMAL';
case GOOD:
return 'resultsNORMAL';
case SHIT:
return 'resultsSHIT';
default:
return 'resultsNORMAL';
}
}
public function hasMusicIntro():Bool
{
switch (abstract)
{
case EXCELLENT:
return true;
case SHIT:
return true;
default:
return false;
}
}
public function getFreeplayRankIconAsset():String public function getFreeplayRankIconAsset():String
{ {
switch (abstract) switch (abstract)

View file

@ -386,6 +386,7 @@ class FreeplayDJ extends FlxAtlasSprite
} }
else else
{ {
FlxG.log.warn("Freeplay character does not have 'charSelect' animation!");
currentState = Confirm; currentState = Confirm;
// Call this immediately; otherwise, we get locked out of Character Select. // Call this immediately; otherwise, we get locked out of Character Select.
onCharSelectComplete(); onCharSelectComplete();

View file

@ -119,6 +119,27 @@ class PlayableCharacter implements IRegistryEntry<PlayerData>
} }
} }
public function getResultsMusicPath(rank:ScoringRank):String
{
switch (rank)
{
case PERFECT_GOLD:
return _data?.results?.music?.PERFECT_GOLD ?? "resultsPERFECT";
case PERFECT:
return _data?.results?.music?.PERFECT ?? "resultsPERFECT";
case EXCELLENT:
return _data?.results?.music?.EXCELLENT ?? "resultsEXCELLENT";
case GREAT:
return _data?.results?.music?.GREAT ?? "resultsNORMAL";
case GOOD:
return _data?.results?.music?.GOOD ?? "resultsNORMAL";
case SHIT:
return _data?.results?.music?.SHIT ?? "resultsSHIT";
default:
return _data?.results?.music?.GOOD ?? "resultsNORMAL";
}
}
/** /**
* Returns whether this character is unlocked. * Returns whether this character is unlocked.
*/ */