Fixes to Character preview window

This commit is contained in:
EliteMasterEric 2023-06-08 16:48:13 -04:00
parent 91a9c385b3
commit ac876c2f59

View file

@ -1,25 +1,19 @@
package funkin.ui.haxeui.components;
import flixel.FlxSprite;
import flixel.graphics.frames.FlxAtlasFrames;
import flixel.graphics.frames.FlxFramesCollection;
import flixel.math.FlxRect;
import funkin.modding.events.ScriptEvent;
import funkin.modding.IScriptedClass.IPlayStateScriptedClass;
import funkin.modding.events.ScriptEvent.GhostMissNoteScriptEvent;
import funkin.modding.events.ScriptEvent.NoteScriptEvent;
import funkin.modding.events.ScriptEvent.SongTimeScriptEvent;
import funkin.modding.events.ScriptEvent.UpdateScriptEvent;
import haxe.ui.core.IDataComponent;
import funkin.play.character.BaseCharacter;
import funkin.play.character.CharacterData.CharacterDataParser;
import haxe.ui.containers.Box;
import haxe.ui.core.Component;
import haxe.ui.core.IDataComponent;
import haxe.ui.data.DataSource;
import haxe.ui.events.AnimationEvent;
import haxe.ui.events.UIEvent;
import haxe.ui.geom.Size;
import haxe.ui.layouts.DefaultLayout;
import haxe.ui.styles.Style;
import openfl.Assets;
private typedef AnimationInfo =
typedef AnimationInfo =
{
var name:String;
var prefix:String;
@ -29,6 +23,10 @@ private typedef AnimationInfo =
var flipY:Null<Bool>; // default false
}
/**
* A variant of SparrowPlayer which loads a BaseCharacter instead.
* This allows it to play appropriate animations based on song events.
*/
@:composite(Layout)
class CharacterPlayer extends Box
{
@ -37,7 +35,7 @@ class CharacterPlayer extends Box
public function new(?defaultToBf:Bool = true)
{
super();
this._overrideSkipTransformChildren = false;
_overrideSkipTransformChildren = false;
if (defaultToBf)
{
@ -45,52 +43,39 @@ class CharacterPlayer extends Box
}
}
var _charId:String;
public var charId(get, set):String;
function get_charId():String
{
return _charId;
return character.characterId;
}
function set_charId(value:String):String
{
_charId = value;
loadCharacter(_charId);
loadCharacter(value);
return value;
}
var _redispatchLoaded:Bool = false; // possible haxeui bug: if listener is added after event is dispatched, event is "lost"... needs thinking about, is it smart to "collect and redispatch"? Not sure
var _redispatchStart:Bool = false; // possible haxeui bug: if listener is added after event is dispatched, event is "lost"... needs thinking about, is it smart to "collect and redispatch"? Not sure
public var charName(get, null):String;
public override function onReady()
function get_charName():String
{
super.onReady();
invalidateComponentLayout();
if (_redispatchLoaded)
{
_redispatchLoaded = false;
dispatch(new AnimationEvent(AnimationEvent.LOADED));
}
if (_redispatchStart)
{
_redispatchStart = false;
dispatch(new AnimationEvent(AnimationEvent.START));
}
parentComponent._overrideSkipTransformChildren = false;
return character.characterName;
}
public function loadCharacter(id:String)
// possible haxeui bug: if listener is added after event is dispatched, event is "lost"... is it smart to "collect and redispatch"? Not sure
var _redispatchLoaded:Bool = false;
// possible haxeui bug: if listener is added after event is dispatched, event is "lost"... is it smart to "collect and redispatch"? Not sure
var _redispatchStart:Bool = false;
var _characterLoaded:Bool = false;
/**
* Loads a character by ID.
* @param id The ID of the character to load.
*/
public function loadCharacter(id:String):Void
{
if (id == null)
{
return;
}
if (id == null) return;
if (character != null)
{
@ -99,34 +84,24 @@ class CharacterPlayer extends Box
character = null;
}
var newCharacter:BaseCharacter = CharacterDataParser.fetchCharacter(id);
if (newCharacter == null)
{
return;
}
// Prevent script issues by fetching with debug=true.
var newCharacter:BaseCharacter = CharacterDataParser.fetchCharacter(id, true);
if (newCharacter == null) return; // Fail if character doesn't exist.
// Assign character.
character = newCharacter;
if (_characterType != null)
{
character.characterType = _characterType;
}
if (flip)
{
character.flipX = !character.flipX;
}
character.scale.x *= _scale;
character.scale.y *= _scale;
// Set character properties.
if (characterType != null) character.characterType = characterType;
if (flip) character.flipX = !character.flipX;
if (targetScale != 1.0) character.setScale(targetScale);
character.animation.callback = function(name:String = "", frameNumber:Int = -1, frameIndex:Int = -1)
{
character.animation.callback = function(name:String = '', frameNumber:Int = -1, frameIndex:Int = -1) {
@:privateAccess
character.onAnimationFrame(name, frameNumber, frameIndex);
dispatch(new AnimationEvent(AnimationEvent.FRAME));
};
character.animation.finishCallback = function(name:String = "")
{
character.animation.finishCallback = function(name:String = '') {
@:privateAccess
character.onAnimationFinished(name);
dispatch(new AnimationEvent(AnimationEvent.END));
@ -145,28 +120,15 @@ class CharacterPlayer extends Box
}
}
override function repositionChildren()
/**
* The character type (such as BF, Dad, GF, etc).
*/
public var characterType(default, set):CharacterType;
function set_characterType(value:CharacterType):CharacterType
{
super.repositionChildren();
@:privateAccess
var animOffsets = character.animOffsets;
character.x = this.screenX + ((this.width / 2) - (character.frameWidth / 2));
character.x -= animOffsets[0];
character.y = this.screenY + ((this.height / 2) - (character.frameHeight / 2));
character.y -= animOffsets[1];
}
var _characterType:CharacterType;
public function setCharacterType(value:CharacterType)
{
_characterType = value;
if (character != null)
{
character.characterType = value;
}
if (character != null) character.characterType = value;
return characterType = value;
}
public var flip(default, set):Bool;
@ -183,89 +145,133 @@ class CharacterPlayer extends Box
return flip = value;
}
var _scale:Float = 1.0;
public var targetScale(default, set):Float = 1.0;
public function setScale(value)
function set_targetScale(value:Float):Float
{
_scale = value;
if (value == targetScale) return value;
if (character != null)
{
character.scale.x *= _scale;
character.scale.y *= _scale;
character.setScale(value);
}
return targetScale = value;
}
public function onUpdate(event:UpdateScriptEvent)
function onFrame(name:String, frameNumber:Int, frameIndex:Int):Void
{
dispatch(new AnimationEvent(AnimationEvent.FRAME));
}
function onFinish(name:String):Void
{
dispatch(new AnimationEvent(AnimationEvent.END));
}
override function repositionChildren():Void
{
super.repositionChildren();
character.x = this.screenX;
character.y = this.screenY;
// Apply animation offsets, so the character is positioned correctly based on the animation.
@:privateAccess var animOffsets:Array<Float> = character.animOffsets;
character.x -= animOffsets[0] * targetScale * (flip ? -1 : 1);
character.y -= animOffsets[1] * targetScale;
}
/**
* Called when an update event is hit in the song.
* Used to play character animations.
* @param event The event.
*/
public function onUpdate(event:UpdateScriptEvent):Void
{
if (character != null) character.onUpdate(event);
}
/**
* Called when an beat is hit in the song
* Used to play character animations.
* @param event The event.
*/
public function onBeatHit(event:SongTimeScriptEvent):Void
{
if (character != null) character.onBeatHit(event);
this.repositionChildren();
}
/**
* Called when a step is hit in the song
* Used to play character animations.
* @param event The event.
*/
public function onStepHit(event:SongTimeScriptEvent):Void
{
if (character != null) character.onStepHit(event);
}
/**
* Called when a note is hit in the song
* Used to play character animations.
* @param event The event.
*/
public function onNoteHit(event:NoteScriptEvent):Void
{
if (character != null) character.onNoteHit(event);
this.repositionChildren();
}
/**
* Called when a note is missed in the song
* Used to play character animations.
* @param event The event.
*/
public function onNoteMiss(event:NoteScriptEvent):Void
{
if (character != null) character.onNoteMiss(event);
this.repositionChildren();
}
/**
* Called when a key is pressed but no note is hit in the song
* Used to play character animations.
* @param event The event.
*/
public function onNoteGhostMiss(event:GhostMissNoteScriptEvent):Void
{
if (character != null) character.onNoteGhostMiss(event);
this.repositionChildren();
}
}
@:access(funkin.ui.haxeui.components.CharacterPlayer)
private class Layout extends DefaultLayout
{
public override function repositionChildren()
public override function resizeChildren():Void
{
var player = cast(_component, CharacterPlayer);
var sprite:BaseCharacter = player.character;
if (sprite == null)
super.resizeChildren();
var player:CharacterPlayer = cast(_component, CharacterPlayer);
var character:BaseCharacter = player.character;
if (character == null)
{
return super.repositionChildren();
return super.resizeChildren();
}
@:privateAccess
var animOffsets = sprite.animOffsets;
sprite.x = _component.screenLeft + ((_component.width / 2) - (sprite.frameWidth / 2));
sprite.x += animOffsets[0];
sprite.y = _component.screenTop + ((_component.height / 2) - (sprite.frameHeight / 2));
sprite.y += animOffsets[1];
character.cornerPosition.set(0, 0);
// character.setGraphicSize(Std.int(innerWidth), Std.int(innerHeight));
}
public override function calcAutoSize(exclusions:Array<Component> = null):Size
{
var player = cast(_component, CharacterPlayer);
var sprite = player.character;
if (sprite == null)
var player:CharacterPlayer = cast(_component, CharacterPlayer);
var character:BaseCharacter = player.character;
if (character == null)
{
return super.calcAutoSize(exclusions);
}
var size = new Size();
size.width = sprite.frameWidth + paddingLeft + paddingRight;
size.height = sprite.frameHeight + paddingTop + paddingBottom;
var size:Size = new Size();
size.width = character.width + paddingLeft + paddingRight;
size.height = character.height + paddingTop + paddingBottom;
return size;
}
}