mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-03-22 18:09:33 +00:00
Merge remote-tracking branch 'origin/rewrite/master' into feature/play-state-note-polish
This commit is contained in:
commit
e0dfdd40a2
2
assets
2
assets
|
@ -1 +1 @@
|
||||||
Subproject commit 9d305889f2e310afeddcda6a4be775eb630fb9ac
|
Subproject commit 9b9baa6f2b38dc9bd3354b350084f548e1e16c0f
|
4
hmm.json
4
hmm.json
|
@ -54,14 +54,14 @@
|
||||||
"name": "haxeui-core",
|
"name": "haxeui-core",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "2561076c5abeee0a60f3a2a65a8ecb7832a6a62a",
|
"ref": "bb904f8b4b205755a310c23ff25219f9dcd62711",
|
||||||
"url": "https://github.com/haxeui/haxeui-core"
|
"url": "https://github.com/haxeui/haxeui-core"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "haxeui-flixel",
|
"name": "haxeui-flixel",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "9c8ab039524086f5a8c8f35b9fb14538b5bfba5d",
|
"ref": "1ec470c297afd7758a90dc9399aa1e3a4ea6ca0b",
|
||||||
"url": "https://github.com/haxeui/haxeui-flixel"
|
"url": "https://github.com/haxeui/haxeui-flixel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,6 +107,26 @@ class FunkinSound extends FlxSound
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the user clicks to focus on the window.
|
||||||
|
*/
|
||||||
|
override function onFocus():Void
|
||||||
|
{
|
||||||
|
if (!_alreadyPaused && this._shouldPlay)
|
||||||
|
{
|
||||||
|
resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the user tabs away from the window.
|
||||||
|
*/
|
||||||
|
override function onFocusLost():Void
|
||||||
|
{
|
||||||
|
_alreadyPaused = _paused;
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
|
||||||
public override function resume():FunkinSound
|
public override function resume():FunkinSound
|
||||||
{
|
{
|
||||||
if (this._time < 0)
|
if (this._time < 0)
|
||||||
|
|
|
@ -132,6 +132,12 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override function destroy()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all sounds from the group.
|
* Remove all sounds from the group.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package funkin.play.character;
|
package funkin.play.character;
|
||||||
|
|
||||||
|
import flixel.graphics.frames.FlxAtlasFrames;
|
||||||
import flixel.graphics.frames.FlxFramesCollection;
|
import flixel.graphics.frames.FlxFramesCollection;
|
||||||
import funkin.modding.events.ScriptEvent;
|
import funkin.modding.events.ScriptEvent;
|
||||||
import funkin.util.assets.FlxAnimationUtil;
|
import funkin.util.assets.FlxAnimationUtil;
|
||||||
|
@ -7,35 +8,17 @@ import funkin.play.character.CharacterData.CharacterRenderType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For some characters which use Sparrow atlases, the spritesheets need to be split
|
* For some characters which use Sparrow atlases, the spritesheets need to be split
|
||||||
* into multiple files. This character renderer handles by showing the appropriate sprite.
|
* into multiple files. This character renderer concatenates these together into a single sprite.
|
||||||
*
|
*
|
||||||
* Examples in base game include BF Holding GF (most of the sprites are in one file
|
* Examples in base game include BF Holding GF (most of the sprites are in one file
|
||||||
* but the death animation is in a separate file).
|
* but the death animation is in a separate file).
|
||||||
* Only example I can think of in mods is Tricky (which has a separate file for each animation).
|
* Only example I can think of in mods is Tricky (which has a separate file for each animation).
|
||||||
*
|
*
|
||||||
* BaseCharacter has game logic, SparrowCharacter has only rendering logic.
|
* BaseCharacter has game logic, MultiSparrowCharacter has only rendering logic.
|
||||||
* KEEP THEM SEPARATE!
|
* KEEP THEM SEPARATE!
|
||||||
*
|
|
||||||
* TODO: Rewrite this to use a single frame collection.
|
|
||||||
* @see https://github.com/HaxeFlixel/flixel/issues/2587#issuecomment-1179620637
|
|
||||||
*/
|
*/
|
||||||
class MultiSparrowCharacter extends BaseCharacter
|
class MultiSparrowCharacter extends BaseCharacter
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The actual group which holds all spritesheets this character uses.
|
|
||||||
*/
|
|
||||||
var members:Map<String, FlxFramesCollection> = new Map<String, FlxFramesCollection>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A map between animation names and what frame collection the animation should use.
|
|
||||||
*/
|
|
||||||
var animAssetPath:Map<String, String> = new Map<String, String>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current frame collection being used.
|
|
||||||
*/
|
|
||||||
var activeMember:String;
|
|
||||||
|
|
||||||
public function new(id:String)
|
public function new(id:String)
|
||||||
{
|
{
|
||||||
super(id, CharacterRenderType.MultiSparrow);
|
super(id, CharacterRenderType.MultiSparrow);
|
||||||
|
@ -51,7 +34,7 @@ class MultiSparrowCharacter extends BaseCharacter
|
||||||
|
|
||||||
function buildSprites():Void
|
function buildSprites():Void
|
||||||
{
|
{
|
||||||
buildSpritesheets();
|
buildSpritesheet();
|
||||||
buildAnimations();
|
buildAnimations();
|
||||||
|
|
||||||
if (_data.isPixel)
|
if (_data.isPixel)
|
||||||
|
@ -66,96 +49,50 @@ class MultiSparrowCharacter extends BaseCharacter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSpritesheets():Void
|
function buildSpritesheet():Void
|
||||||
{
|
{
|
||||||
// TODO: This currently works by creating like 5 frame collections and switching between them.
|
var assetList = [];
|
||||||
// It would be better to refactor this to simply concatenate the frame collections together.
|
|
||||||
|
|
||||||
// Build the list of asset paths to use.
|
|
||||||
// Ignore nulls and duplicates.
|
|
||||||
var assetList = [_data.assetPath];
|
|
||||||
for (anim in _data.animations)
|
for (anim in _data.animations)
|
||||||
{
|
{
|
||||||
if (anim.assetPath != null && !assetList.contains(anim.assetPath))
|
if (anim.assetPath != null && !assetList.contains(anim.assetPath))
|
||||||
{
|
{
|
||||||
assetList.push(anim.assetPath);
|
assetList.push(anim.assetPath);
|
||||||
}
|
}
|
||||||
animAssetPath.set(anim.name, anim.assetPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the Sparrow atlas for each path and store them in the members map.
|
var texture:FlxAtlasFrames = Paths.getSparrowAtlas(_data.assetPath, 'shared');
|
||||||
for (asset in assetList)
|
|
||||||
{
|
|
||||||
var texture:FlxFramesCollection = Paths.getSparrowAtlas(asset, 'shared');
|
|
||||||
// If we don't do this, the unused textures will be removed as soon as they're loaded.
|
|
||||||
|
|
||||||
if (texture == null)
|
if (texture == null)
|
||||||
{
|
{
|
||||||
trace('Multi-Sparrow atlas could not load texture: ${asset}');
|
trace('Multi-Sparrow atlas could not load PRIMARY texture: ${_data.assetPath}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trace('Adding multi-sparrow atlas: ${asset}');
|
trace('Creating multi-sparrow atlas: ${_data.assetPath}');
|
||||||
texture.parent.destroyOnNoUse = false;
|
texture.parent.destroyOnNoUse = false;
|
||||||
members.set(asset, texture);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the default frame collection to start.
|
for (asset in assetList)
|
||||||
loadFramesByAssetPath(_data.assetPath);
|
{
|
||||||
|
var subTexture:FlxAtlasFrames = Paths.getSparrowAtlas(asset, 'shared');
|
||||||
|
// If we don't do this, the unused textures will be removed as soon as they're loaded.
|
||||||
|
|
||||||
|
if (subTexture == null)
|
||||||
|
{
|
||||||
|
trace('Multi-Sparrow atlas could not load subtexture: ${asset}');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trace('Concatenating multi-sparrow atlas: ${asset}');
|
||||||
|
subTexture.parent.destroyOnNoUse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
texture.addAtlas(subTexture);
|
||||||
* Replace this sprite's animation frames with the ones at this asset path.
|
|
||||||
*/
|
|
||||||
function loadFramesByAssetPath(assetPath:String):Void
|
|
||||||
{
|
|
||||||
if (_data.assetPath == null)
|
|
||||||
{
|
|
||||||
trace('[ERROR] Multi-Sparrow character has no default asset path!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (assetPath == null)
|
|
||||||
{
|
|
||||||
// trace('Asset path is null, falling back to default. This is normal!');
|
|
||||||
loadFramesByAssetPath(_data.assetPath);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.activeMember == assetPath)
|
this.frames = texture;
|
||||||
{
|
|
||||||
// trace('Already using this asset path: ${assetPath}');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (members.exists(assetPath))
|
|
||||||
{
|
|
||||||
// Switch to a new set of sprites.
|
|
||||||
// trace('Loading frames from asset path: ${assetPath}');
|
|
||||||
this.frames = members.get(assetPath);
|
|
||||||
this.activeMember = assetPath;
|
|
||||||
this.setScale(_data.scale);
|
this.setScale(_data.scale);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
trace('[WARN] MultiSparrow character ${characterId} could not find asset path: ${assetPath}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace this sprite's animation frames with the ones needed to play this animation.
|
|
||||||
*/
|
|
||||||
function loadFramesByAnimName(animName)
|
|
||||||
{
|
|
||||||
if (animAssetPath.exists(animName))
|
|
||||||
{
|
|
||||||
loadFramesByAssetPath(animAssetPath.get(animName));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
trace('[WARN] MultiSparrow character ${characterId} could not find animation: ${animName}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildAnimations()
|
function buildAnimations()
|
||||||
{
|
{
|
||||||
|
@ -164,7 +101,6 @@ class MultiSparrowCharacter extends BaseCharacter
|
||||||
// We need to swap to the proper frame collection before adding the animations, I think?
|
// We need to swap to the proper frame collection before adding the animations, I think?
|
||||||
for (anim in _data.animations)
|
for (anim in _data.animations)
|
||||||
{
|
{
|
||||||
loadFramesByAnimName(anim.name);
|
|
||||||
FlxAnimationUtil.addAtlasAnimation(this, anim);
|
FlxAnimationUtil.addAtlasAnimation(this, anim);
|
||||||
|
|
||||||
if (anim.offsets == null)
|
if (anim.offsets == null)
|
||||||
|
@ -187,37 +123,6 @@ class MultiSparrowCharacter extends BaseCharacter
|
||||||
// unless we're forcing a new animation.
|
// unless we're forcing a new animation.
|
||||||
if (!this.canPlayOtherAnims && !ignoreOther) return;
|
if (!this.canPlayOtherAnims && !ignoreOther) return;
|
||||||
|
|
||||||
loadFramesByAnimName(name);
|
|
||||||
super.playAnimation(name, restart, ignoreOther, reverse);
|
super.playAnimation(name, restart, ignoreOther, reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
override function set_frames(value:FlxFramesCollection):FlxFramesCollection
|
|
||||||
{
|
|
||||||
// DISABLE THIS SO WE DON'T DESTROY OUR HARD WORK
|
|
||||||
// WE WILL MAKE SURE TO LOAD THE PROPER SPRITESHEET BEFORE PLAYING AN ANIM
|
|
||||||
// if (animation != null)
|
|
||||||
// {
|
|
||||||
// animation.destroyAnimations();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
graphic = value.parent;
|
|
||||||
this.frames = value;
|
|
||||||
this.frame = value.getByIndex(0);
|
|
||||||
// this.numFrames = value.numFrames;
|
|
||||||
resetHelpers();
|
|
||||||
this.bakedRotationAngle = 0;
|
|
||||||
this.animation.frameIndex = 0;
|
|
||||||
graphicLoaded();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.frames = null;
|
|
||||||
this.frame = null;
|
|
||||||
this.graphic = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.frames;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5951,9 +5951,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
ChartEditorNoteSprite.noteFrameCollection = null;
|
ChartEditorNoteSprite.noteFrameCollection = null;
|
||||||
|
|
||||||
// Stop the music.
|
// Stop the music.
|
||||||
welcomeMusic.destroy();
|
if (welcomeMusic != null) welcomeMusic.destroy();
|
||||||
audioInstTrack.destroy();
|
if (audioInstTrack != null) audioInstTrack.destroy();
|
||||||
audioVocalTrackGroup.destroy();
|
if (audioVocalTrackGroup != null) audioVocalTrackGroup.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCanQuickSave():Void
|
function applyCanQuickSave():Void
|
||||||
|
|
|
@ -25,6 +25,10 @@ class ChartEditorEventContextMenu extends ChartEditorBaseContextMenu
|
||||||
|
|
||||||
function initialize()
|
function initialize()
|
||||||
{
|
{
|
||||||
|
contextmenuEdit.onClick = function(_) {
|
||||||
|
chartEditorState.showToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_EVENT_DATA_LAYOUT);
|
||||||
|
}
|
||||||
|
|
||||||
contextmenuDelete.onClick = function(_) {
|
contextmenuDelete.onClick = function(_) {
|
||||||
chartEditorState.performCommand(new RemoveEventsCommand([data]));
|
chartEditorState.performCommand(new RemoveEventsCommand([data]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -995,7 +995,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the difficulty star count on the right.
|
// Set the difficulty star count on the right.
|
||||||
difficultyStars.difficulty = daSong.songRating;
|
difficultyStars.difficulty = daSong?.songRating ?? difficultyStars.difficulty; // yay haxe 4.3
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears the cache of songs, frees up memory, they' ll have to be loaded in later tho function clearDaCache(actualSongTho:String)
|
// Clears the cache of songs, frees up memory, they' ll have to be loaded in later tho function clearDaCache(actualSongTho:String)
|
||||||
|
|
Loading…
Reference in a new issue