Merge branch 'rewrite/master' into bugfix/freeplay-afk-fixes

This commit is contained in:
Eric 2024-03-26 19:35:10 -04:00 committed by GitHub
commit 88c973f1ae
22 changed files with 245 additions and 44 deletions

View file

@ -13,8 +13,9 @@ jobs:
apt update
apt install -y sudo git curl unzip
- name: Fix git config on posix runner
# this can't be {{ github.workspace }} because that's not docker-aware
run: |
git config --global --add safe.directory ${{ github.workspace }}
git config --global --add safe.directory $GITHUB_WORKSPACE
- name: Get checkout token
uses: actions/create-github-app-token@v1
id: app_token
@ -90,8 +91,9 @@ jobs:
runs-on: [self-hosted, macos]
steps:
- name: Fix git config on posix runner
# this can't be {{ github.workspace }} because that's not docker-aware
run: |
git config --global --add safe.directory ${{ github.workspace }}
git config --global --add safe.directory $GITHUB_WORKSPACE
- name: Get checkout token
uses: actions/create-github-app-token@v1
id: app_token

15
.vscode/settings.json vendored
View file

@ -204,6 +204,21 @@
"label": "HTML5 / Debug (Watch)",
"target": "html5",
"args": ["-debug", "-watch", "-DFORCE_DEBUG_VERSION"]
},
{
"label": "macOS / Debug",
"target": "mac",
"args": ["-debug", "-DFORCE_DEBUG_VERSION"]
},
{
"label": "macOS / Release",
"target": "mac",
"args": ["-release"]
},
{
"label": "macOS / Release (GitHub Actions)",
"target": "mac",
"args": ["-release", "-DGITHUB_BUILD"]
}
],
"cmake.configureOnOpen": false,

2
assets

@ -1 +1 @@
Subproject commit 3e8bea70e7dcc76df67a0e87b85ef28ed5140371
Subproject commit 5f1726f1b0c11fc747b7473708cf4e5f28be05f1

View file

@ -35,7 +35,15 @@ class Conductor
* You can also do stuff like store a reference to the Conductor and pass it around or temporarily replace it,
* or have a second Conductor running at the same time, or other weird stuff like that if you need to.
*/
public static var instance:Conductor = new Conductor();
public static var instance(get, never):Conductor;
static var _instance:Null<Conductor> = null;
static function get_instance():Conductor
{
if (_instance == null) _instance = new Conductor();
return _instance;
}
/**
* Signal fired when the current Conductor instance advances to a new measure.
@ -523,6 +531,6 @@ class Conductor
*/
public static function reset():Void
{
Conductor.instance = new Conductor();
_instance = new Conductor();
}
}

View file

@ -55,6 +55,13 @@ abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructo
this.entries = new Map<String, T>();
this.scriptedEntryIds = [];
// Lazy initialization of singletons should let this get called,
// but we have this check just in case.
if (FlxG.game != null)
{
FlxG.console.registerObject('registry$registryId', this);
}
}
/**

View file

@ -15,7 +15,14 @@ class ConversationRegistry extends BaseRegistry<Conversation, ConversationData>
public static final CONVERSATION_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";
public static final instance:ConversationRegistry = new ConversationRegistry();
public static var instance(get, never):ConversationRegistry;
static var _instance:Null<ConversationRegistry> = null;
static function get_instance():ConversationRegistry
{
if (_instance == null) _instance = new ConversationRegistry();
return _instance;
}
public function new()
{

View file

@ -15,7 +15,14 @@ class DialogueBoxRegistry extends BaseRegistry<DialogueBox, DialogueBoxData>
public static final DIALOGUEBOX_DATA_VERSION_RULE:thx.semver.VersionRule = "1.1.x";
public static final instance:DialogueBoxRegistry = new DialogueBoxRegistry();
public static var instance(get, never):DialogueBoxRegistry;
static var _instance:Null<DialogueBoxRegistry> = null;
static function get_instance():DialogueBoxRegistry
{
if (_instance == null) _instance = new DialogueBoxRegistry();
return _instance;
}
public function new()
{

View file

@ -15,7 +15,14 @@ class SpeakerRegistry extends BaseRegistry<Speaker, SpeakerData>
public static final SPEAKER_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";
public static final instance:SpeakerRegistry = new SpeakerRegistry();
public static var instance(get, never):SpeakerRegistry;
static var _instance:Null<SpeakerRegistry> = null;
static function get_instance():SpeakerRegistry
{
if (_instance == null) _instance = new SpeakerRegistry();
return _instance;
}
public function new()
{

View file

@ -15,7 +15,14 @@ class LevelRegistry extends BaseRegistry<Level, LevelData>
public static final LEVEL_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";
public static final instance:LevelRegistry = new LevelRegistry();
public static var instance(get, never):LevelRegistry;
static var _instance:Null<LevelRegistry> = null;
static function get_instance():LevelRegistry
{
if (_instance == null) _instance = new LevelRegistry();
return _instance;
}
public function new()
{

View file

@ -15,7 +15,14 @@ class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData>
public static final NOTE_STYLE_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";
public static final instance:NoteStyleRegistry = new NoteStyleRegistry();
public static var instance(get, never):NoteStyleRegistry;
static var _instance:Null<NoteStyleRegistry> = null;
static function get_instance():NoteStyleRegistry
{
if (_instance == null) _instance = new NoteStyleRegistry();
return _instance;
}
public function new()
{

View file

@ -40,10 +40,17 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata>
}
/**
* TODO: What if there was a Singleton macro which created static functions
* that redirected to the instance?
* TODO: What if there was a Singleton macro which automatically created the property for us?
*/
public static final instance:SongRegistry = new SongRegistry();
public static var instance(get, never):SongRegistry;
static var _instance:Null<SongRegistry> = null;
static function get_instance():SongRegistry
{
if (_instance == null) _instance = new SongRegistry();
return _instance;
}
public function new()
{

View file

@ -15,7 +15,14 @@ class StageRegistry extends BaseRegistry<Stage, StageData>
public static final STAGE_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x";
public static final instance:StageRegistry = new StageRegistry();
public static var instance(get, never):StageRegistry;
static var _instance:Null<StageRegistry> = null;
static function get_instance():StageRegistry
{
if (_instance == null) _instance = new StageRegistry();
return _instance;
}
public function new()
{

View file

@ -1364,7 +1364,10 @@ class PlayState extends MusicBeatSubState
}
// Only zoom camera if we are zoomed by less than 35%.
if (FlxG.camera.zoom < (1.35 * defaultCameraZoom) && cameraZoomRate > 0 && Conductor.instance.currentBeat % cameraZoomRate == 0)
if (Preferences.zoomCamera
&& FlxG.camera.zoom < (1.35 * defaultCameraZoom)
&& cameraZoomRate > 0
&& Conductor.instance.currentBeat % cameraZoomRate == 0)
{
// Zoom camera in (1.5%)
currentCameraZoom += cameraZoomIntensity * defaultCameraZoom;
@ -2106,8 +2109,7 @@ class PlayState extends MusicBeatSubState
holdNote.handledMiss = true;
// We dropped a hold note.
// Mute vocals and play miss animation, but don't penalize.
vocals.opponentVolume = 0;
// Play miss animation, but don't penalize.
currentStage.getOpponent().playSingAnimation(holdNote.noteData.getDirection(), true);
}
}
@ -2939,7 +2941,10 @@ class PlayState extends MusicBeatSubState
if (overrideMusic)
{
// Stop the music. Do NOT destroy it, something still references it!
FlxG.sound.music.pause();
if (FlxG.sound.music != null)
{
FlxG.sound.music.pause();
}
if (vocals != null)
{
vocals.pause();
@ -2949,7 +2954,10 @@ class PlayState extends MusicBeatSubState
else
{
// Stop and destroy the music.
FlxG.sound.music.pause();
if (FlxG.sound.music != null)
{
FlxG.sound.music.pause();
}
if (vocals != null)
{
vocals.destroy();

View file

@ -109,7 +109,7 @@ class ResultState extends MusicBeatSubState
add(gf);
var boyfriend:FlxSprite = FunkinSprite.createSparrow(640, -200, 'resultScreen/resultBoyfriendGOOD');
boyfriend.animation.addByPrefix("fall", "Boyfriend Good", 24, false);
boyfriend.animation.addByPrefix("fall", "Boyfriend Good Anim0", 24, false);
boyfriend.visible = false;
boyfriend.animation.finishCallback = function(_) {
boyfriend.animation.play('fall', true, false, 14);
@ -164,7 +164,7 @@ class ResultState extends MusicBeatSubState
add(blackTopBar);
var resultsAnim:FunkinSprite = FunkinSprite.createSparrow(-200, -10, "resultScreen/results");
resultsAnim.animation.addByPrefix("result", "results", 24, false);
resultsAnim.animation.addByPrefix("result", "results instance 1", 24, false);
resultsAnim.animation.play("result");
add(resultsAnim);

View file

@ -76,10 +76,17 @@ class AnimateAtlasCharacter extends BaseCharacter
{
trace('Creating Animate Atlas character: ' + this.characterId);
var atlasSprite:FlxAtlasSprite = loadAtlasSprite();
setSprite(atlasSprite);
try
{
var atlasSprite:FlxAtlasSprite = loadAtlasSprite();
setSprite(atlasSprite);
loadAnimations();
loadAnimations();
}
catch (e)
{
throw "Exception thrown while building FlxAtlasSprite: " + e;
}
super.onCreate(event);
}

View file

@ -5,6 +5,7 @@ import flixel.FlxSprite;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import flixel.util.FlxSignal;
import flixel.util.FlxTimer;
#if html5
import funkin.graphics.video.FlxVideo;
@ -28,6 +29,31 @@ class VideoCutscene
static var vid:FlxVideoSprite;
#end
/**
* Called when the video is started.
*/
public static final onVideoStarted:FlxSignal = new FlxSignal();
/**
* Called if the video is paused.
*/
public static final onVideoPaused:FlxSignal = new FlxSignal();
/**
* Called if the video is resumed.
*/
public static final onVideoResumed:FlxSignal = new FlxSignal();
/**
* Called if the video is restarted. onVideoStarted is not called.
*/
public static final onVideoRestarted:FlxSignal = new FlxSignal();
/**
* Called when the video is ended or skipped.
*/
public static final onVideoEnded:FlxSignal = new FlxSignal();
/**
* Play a video cutscene.
* TODO: Currently this is hardcoded to start the countdown after the video is done.
@ -94,6 +120,8 @@ class VideoCutscene
PlayState.instance.add(vid);
PlayState.instance.refresh();
onVideoStarted.dispatch();
}
else
{
@ -129,6 +157,8 @@ class VideoCutscene
vid.y = 0;
// vid.scale.set(0.5, 0.5);
});
onVideoStarted.dispatch();
}
else
{
@ -143,6 +173,7 @@ class VideoCutscene
if (vid != null)
{
vid.restartVideo();
onVideoRestarted.dispatch();
}
#end
@ -156,6 +187,8 @@ class VideoCutscene
// Resume the video if it was paused.
vid.resume();
}
onVideoRestarted.dispatch();
}
#end
}
@ -166,6 +199,7 @@ class VideoCutscene
if (vid != null)
{
vid.pauseVideo();
onVideoPaused.dispatch();
}
#end
@ -173,6 +207,45 @@ class VideoCutscene
if (vid != null)
{
vid.pause();
onVideoPaused.dispatch();
}
#end
}
public static function hideVideo():Void
{
#if html5
if (vid != null)
{
vid.visible = false;
blackScreen.visible = false;
}
#end
#if hxCodec
if (vid != null)
{
vid.visible = false;
blackScreen.visible = false;
}
#end
}
public static function showVideo():Void
{
#if html5
if (vid != null)
{
vid.visible = true;
blackScreen.visible = false;
}
#end
#if hxCodec
if (vid != null)
{
vid.visible = true;
blackScreen.visible = false;
}
#end
}
@ -183,6 +256,7 @@ class VideoCutscene
if (vid != null)
{
vid.resumeVideo();
onVideoResumed.dispatch();
}
#end
@ -190,6 +264,7 @@ class VideoCutscene
if (vid != null)
{
vid.resume();
onVideoResumed.dispatch();
}
#end
}
@ -240,6 +315,7 @@ class VideoCutscene
{
ease: FlxEase.quadInOut,
onComplete: function(twn:FlxTween) {
onVideoEnded.dispatch();
onCutsceneFinish(cutsceneType);
}
});

View file

@ -139,7 +139,16 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
for (vari in _data.playData.songVariations)
{
var variMeta:Null<SongMetadata> = fetchVariationMetadata(id, vari);
if (variMeta != null) _metadata.set(variMeta.variation, variMeta);
if (variMeta != null)
{
_metadata.set(variMeta.variation, variMeta);
trace(' Loaded variation: $vari');
}
else
{
FlxG.log.warn('[SONG] Failed to load variation metadata (${id}:${vari}), is the path correct?');
trace(' FAILED to load variation: $vari');
}
}
}
@ -374,12 +383,17 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
public function getFirstValidVariation(?diffId:String, ?possibleVariations:Array<String>):Null<String>
{
if (variations == null) possibleVariations = variations;
if (possibleVariations == null)
{
possibleVariations = variations;
possibleVariations.sort(SortUtil.defaultsThenAlphabetically.bind(Constants.DEFAULT_VARIATION_LIST));
}
if (diffId == null) diffId = listDifficulties(null, possibleVariations)[0];
for (variation in variations)
for (variationId in possibleVariations)
{
if (difficulties.exists('$diffId-$variation')) return variation;
var variationSuffix = (variationId != Constants.DEFAULT_VARIATION) ? '-$variationId' : '';
if (difficulties.exists('$diffId$variationSuffix')) return variationId;
}
return null;

View file

@ -1,31 +1,35 @@
package funkin.ui.debug.anim;
import funkin.util.SerializerUtil;
import funkin.play.character.CharacterData;
import flixel.FlxCamera;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.addons.display.FlxGridOverlay;
import flixel.addons.ui.FlxInputText;
import flixel.addons.ui.FlxUIDropDownMenu;
import flixel.FlxCamera;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.graphics.frames.FlxFrame;
import flixel.group.FlxGroup;
import flixel.math.FlxPoint;
import flixel.text.FlxText;
import flixel.util.FlxColor;
import funkin.util.MouseUtil;
import flixel.util.FlxSpriteUtil;
import flixel.util.FlxTimer;
import funkin.audio.FunkinSound;
import funkin.input.Cursor;
import funkin.play.character.BaseCharacter;
import funkin.play.character.CharacterData;
import funkin.play.character.CharacterData.CharacterDataParser;
import funkin.play.character.SparrowCharacter;
import haxe.ui.RuntimeComponentBuilder;
import funkin.ui.mainmenu.MainMenuState;
import funkin.util.MouseUtil;
import funkin.util.SerializerUtil;
import funkin.util.SortUtil;
import haxe.ui.components.DropDown;
import haxe.ui.core.Component;
import haxe.ui.core.Screen;
import haxe.ui.events.ItemEvent;
import haxe.ui.events.UIEvent;
import funkin.ui.mainmenu.MainMenuState;
import haxe.ui.RuntimeComponentBuilder;
import lime.utils.Assets as LimeAssets;
import openfl.Assets;
import openfl.events.Event;
@ -33,13 +37,8 @@ import openfl.events.IOErrorEvent;
import openfl.geom.Rectangle;
import openfl.net.FileReference;
import openfl.net.URLLoader;
import funkin.ui.mainmenu.MainMenuState;
import openfl.net.URLRequest;
import openfl.utils.ByteArray;
import funkin.input.Cursor;
import funkin.play.character.CharacterData.CharacterDataParser;
import funkin.util.SortUtil;
import haxe.ui.core.Screen;
using flixel.util.FlxSpriteUtil;

View file

@ -4948,7 +4948,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
playbarNoteSnap.text = '1/${noteSnapQuant}';
playbarDifficulty.text = '${selectedDifficulty.toTitleCase()}';
// playbarBPM.text = 'BPM: ${(Conductor.currentTimeChange?.bpm ?? 0.0)}';
playbarBPM.text = 'BPM: ${(Conductor.instance.bpm ?? 0.0)}';
}
function handlePlayhead():Void

View file

@ -1013,7 +1013,14 @@ class FreeplayState extends MusicBeatSubState
// Set the difficulty star count on the right.
albumRoll.setDifficultyStars(daSong?.songRating);
albumRoll.albumId = daSong?.albumId ?? Constants.DEFAULT_ALBUM_ID;
// Set the album graphic and play the animation if relevant.
var newAlbumId:String = daSong?.albumId ?? Constants.DEFAULT_ALBUM_ID;
if (albumRoll.albumId != newAlbumId)
{
albumRoll.albumId = newAlbumId;
albumRoll.playIntro();
}
}
// Clears the cache of songs, frees up memory, they' ll have to be loaded in later tho function clearDaCache(actualSongTho:String)

View file

@ -450,7 +450,11 @@ class StoryMenuState extends MusicBeatState
*/
function changeDifficulty(change:Int = 0):Void
{
var difficultyList:Array<String> = currentLevel.getDifficulties();
// "For now, NO erect in story mode" -Dave
var difficultyList:Array<String> = Constants.DEFAULT_DIFFICULTY_LIST;
// Use this line to displays all difficulties
// var difficultyList:Array<String> = currentLevel.getDifficulties();
var currentIndex:Int = difficultyList.indexOf(currentDifficultyId);
currentIndex += change;

View file

@ -157,6 +157,11 @@ class Constants
*/
public static final DEFAULT_VARIATION:String = 'default';
/**
* Standard variations used by the game.
*/
public static final DEFAULT_VARIATION_LIST:Array<String> = ['default', 'erect', 'pico'];
/**
* The default intensity for camera zooms.
*/