Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion source/funkin/data/character/CharacterData.hx
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,12 @@ class CharacterDataParser
input.startingAnimation = DEFAULT_STARTINGANIM;
}

if (input.animPriorityQueue == null)
{
var canDance:Bool = [for (a in input.animations) a.name].contains("danceLeft");
input.animPriorityQueue = ["sing*", (canDance ? "dance*" : "idle")];
}

if (input.scale == null)
{
input.scale = DEFAULT_SCALE;
Expand Down Expand Up @@ -559,7 +565,7 @@ class CharacterDataParser
input.flipX = DEFAULT_FLIPX;
}

if (input.animations.length == 0 && input.startingAnimation != null)
if (input.animations.length == 0 && (input.startingAnimation != null || input.animPriorityQueue != null))
{
return null;
}
Expand Down Expand Up @@ -727,6 +733,12 @@ typedef CharacterData =
*/
var startingAnimation:Null<String>;

/**
* If animations are used, place them here to have some sort of priority queue.
* For example a queue ["sing*", "idle"] would have all animations starting with "sing" on a higher priority than idling.
*/
var animPriorityQueue:Null<Array<String>>;

/**
* Whether or not the whole ass sprite is flipped by default.
* Useful for characters that could also be played (Pico)
Expand Down
5 changes: 3 additions & 2 deletions source/funkin/play/character/BaseCharacter.hx
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ class BaseCharacter extends Bopper

this.characterId = id;

ignoreExclusionPref = ["sing"];

_data = CharacterDataParser.fetchCharacterData(this.characterId);
if (_data == null)
{
Expand All @@ -179,6 +177,9 @@ class BaseCharacter extends Bopper
this.singTimeSteps = _data.singTime;
this.globalOffsets = _data.offsets;
this.flipX = _data.flipX;

var canDance:Bool = this.hasAnimation("danceLeft");
this.animPriorityQueue = _data.animPriorityQueue ?? ["sing*", (canDance ? "dance*" : "idle")];
}

shouldBop = false;
Expand Down
55 changes: 32 additions & 23 deletions source/funkin/play/stage/Bopper.hx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
*/
public var idleSuffix(default, set):String = '';

/**
* The priority queue for the animations.
* The lower the index an animation has, the higher the priority. Animations not in this array have the highest priority.
*/
public var animPriorityQueue:Array<String> = [];

/**
* If this bopper is rendered with pixel art, disable anti-aliasing.
* @default `false`
Expand Down Expand Up @@ -118,7 +124,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
*/
function onAnimationFinished(name:String)
{
// TODO: Can we make a system of like, animation priority or something?
if (!canPlayOtherAnims)
{
canPlayOtherAnims = true;
Expand Down Expand Up @@ -253,8 +258,6 @@ class Bopper extends StageProp implements IPlayStateScriptedClass

public var canPlayOtherAnims:Bool = true;

public var ignoreExclusionPref:Array<String> = [];

/**
* @param name The name of the animation to play.
* @param restart Whether to restart the animation if it is already playing.
Expand All @@ -263,26 +266,7 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
*/
public function playAnimation(name:String, restart:Bool = false, ignoreOther:Bool = false, reversed:Bool = false):Void
{
if ((!canPlayOtherAnims))
{
var id = name;
if (getCurrentAnimation() == id && restart) {}
else if (ignoreExclusionPref != null && ignoreExclusionPref.length > 0)
{
var detected:Bool = false;
for (entry in ignoreExclusionPref)
{
if (StringTools.startsWith(id, entry))
{
detected = true;
break;
}
}
if (!detected) return;
}
else
return;
}
if (!canPlayOtherAnims && !canPlayAnimation(name)) return;

var correctName = correctAnimationName(name);
if (correctName == null) return;
Expand All @@ -297,6 +281,31 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
applyAnimationOffsets(correctName);
}

/**
* Go over the animation priority queue and see if the requested animation can be played.
* @param name The requested animation to play.
*/
function canPlayAnimation(name:String)
{
var requestedPriority:Int = -1;
var currentPriority:Int = -1;

for (i in 0...animPriorityQueue.length)
{
// Format each priority queue member to fit the ereg format.
var queueEntry:String = "^" + animPriorityQueue[i];
var regFormat:String = queueEntry.replace("*", ".+");

if (regFormat.endsWith(".+")) queueEntry = queueEntry.substring(0, queueEntry.length - 1) + "$.+";

if (new EReg(regFormat, "g").match(name) && requestedPriority == -1) requestedPriority = i;
if (new EReg(regFormat, "g").match(getCurrentAnimation()) && currentPriority == -1) currentPriority = i;
}

// An animation can be played if the requestedPriority is smaller or equal to the currentPriority.
return requestedPriority <= currentPriority;
}

var forceAnimationTimer:FlxTimer = new FlxTimer();

/**
Expand Down
Loading