From 1b55beffe906404d8cb39ad63f6fc6b446557e1c Mon Sep 17 00:00:00 2001 From: Ne_Eo Date: Tue, 27 Aug 2024 02:15:45 +0200 Subject: [PATCH] Added number ranges for indices (1..6) --- source/funkin/backend/utils/CoolUtil.hx | 85 +++++++++++++++++++ source/funkin/backend/utils/XMLUtil.hx | 9 +- .../editors/character/CharacterAnimScreen.hx | 10 +-- .../editors/character/CharacterInfoScreen.hx | 4 +- source/funkin/game/Character.hx | 2 +- 5 files changed, 92 insertions(+), 18 deletions(-) diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 63a910b1c..e624a5662 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -777,6 +777,91 @@ class CoolUtil var file = new haxe.io.Path(file); return file.file; } + + /** + * Converts a string of "1..3,5,7..9,8..5" into an array of numbers like [1,2,3,5,7,8,9,8,7,6,5] + * @param input String to parse + * @return Array of numbers + */ + public static function parseNumberRange(input:String):Array { + var result:Array = []; + var parts:Array = input.split(","); + + for (part in parts) { + part = part.trim(); + var idx = part.indexOf(".."); + if (idx != -1) { + var start = Std.parseInt(part.substring(0, idx).trim()); + var end = Std.parseInt(part.substring(idx + 2).trim()); + + if(start == null || end == null) { + continue; + } + + if (start < end) { + for (j in start...end + 1) { + result.push(j); + } + } else { + for (j in end...start + 1) { + result.push(start + end - j); + } + } + } else { + var num = Std.parseInt(part); + if (num != null) { + result.push(num); + } + } + } + return result; + } + + /** + * Converts an array of numbers into a string of ranges. + * Example: [1,2,3,5,7,8,9,8,7,6,5] -> "1..3,5,7..9,8..5" + * @param numbers Array of numbers + * @return String representing the ranges + */ + public static function formatNumberRange(numbers:Array, seperator:String = ","):String { + if (numbers.length == 0) return ""; + + var result:Array = []; + var i = 0; + + while (i < numbers.length) { + var start = numbers[i]; + var end = start; + var direction = 0; // 0: no sequence, 1: increasing, -1: decreasing + + if (i + 1 < numbers.length) { // detect direction of sequence + if (numbers[i + 1] == end + 1) { + direction = 1; + } else if (numbers[i + 1] == end - 1) { + direction = -1; + } + } + + if(direction != 0) { + while (i + 1 < numbers.length && (numbers[i + 1] == end + direction)) { + end = numbers[i + 1]; + i++; + } + } + + if (start == end) { // no direction + result.push('${start}'); + } else if (start + direction == end) { // 1 step increment + result.push('${start},${end}'); + } else { // store as range + result.push('${start}..${end}'); + } + + i++; + } + + return result.join(seperator); + } } /** diff --git a/source/funkin/backend/utils/XMLUtil.hx b/source/funkin/backend/utils/XMLUtil.hx index 23ed0516a..880cd96c1 100644 --- a/source/funkin/backend/utils/XMLUtil.hx +++ b/source/funkin/backend/utils/XMLUtil.hx @@ -209,14 +209,7 @@ class XMLUtil { if (anim.has.y) animData.y = Std.parseFloat(anim.att.y).getDefault(animData.y); if (anim.has.loop) animData.loop = anim.att.loop == "true"; if (anim.has.forced) animData.forced = anim.att.forced == "true"; - if (anim.has.indices) { - var indicesSplit = anim.att.indices.split(","); - for(indice in indicesSplit) { - var i = Std.parseInt(indice.trim()); - if (i != null) - animData.indices.push(i); - } - } + if (anim.has.indices) animData.indices = CoolUtil.parseNumberRange(anim.att.indices); return animData; } diff --git a/source/funkin/editors/character/CharacterAnimScreen.hx b/source/funkin/editors/character/CharacterAnimScreen.hx index 1b64907f7..437ee8a78 100644 --- a/source/funkin/editors/character/CharacterAnimScreen.hx +++ b/source/funkin/editors/character/CharacterAnimScreen.hx @@ -69,7 +69,7 @@ class CharacterAnimScreen extends UISubstateWindow { addLabelOn(loopedCheckbox, "Looping"); loopedCheckbox.x += 8; loopedCheckbox.y += 6; - indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y + 32 + 40, animData.indices.join(", "), 270); + indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y + 32 + 40, CoolUtil.formatNumberRange(animData.indices, ", "), 270); add(indicesTextBox); addLabelOn(indicesTextBox, "Indices"); @@ -109,14 +109,8 @@ class CharacterAnimScreen extends UISubstateWindow { animType: NONE, x: offsetXStepper.value, y: offsetYStepper.value, - indices: [] + indices: CoolUtil.parseNumberRange(indicesTextBox.label.text) }; - var indicesSplit = indicesTextBox.label.text.split(","); - for(indice in indicesSplit) { - var i = Std.parseInt(indice.trim()); - if (i != null) - animData.indices.push(i); - } if (onSave != null) onSave(animData); } diff --git a/source/funkin/editors/character/CharacterInfoScreen.hx b/source/funkin/editors/character/CharacterInfoScreen.hx index 882df52bb..4f44dc81e 100644 --- a/source/funkin/editors/character/CharacterInfoScreen.hx +++ b/source/funkin/editors/character/CharacterInfoScreen.hx @@ -194,8 +194,10 @@ class CharacterInfoScreen extends UISubstateWindow { var offset:FlxPoint = character.getAnimOffset(anim.name); animXml.set("x", Std.string(offset.x)); animXml.set("y", Std.string(offset.y)); + offset.put(); + if (anim.indices.length > 0) - animXml.set("indices", anim.indices.join(",")); + animXml.set("indices", CoolUtil.formatNumberRange(anim.indices)); xml.addChild(animXml); } diff --git a/source/funkin/game/Character.hx b/source/funkin/game/Character.hx index 286ff86ed..d35e930da 100644 --- a/source/funkin/game/Character.hx +++ b/source/funkin/game/Character.hx @@ -373,7 +373,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset offset.putWeak(); if (anim.indices.length > 0) - animXml.set("indices", anim.indices.join(",")); + animXml.set("indices", CoolUtil.formatNumberRange(anim.indices)); xml.addChild(animXml); }