From ab8373d62ec4a96fdb7bb4ab62727f4d7ff87892 Mon Sep 17 00:00:00 2001 From: 3944Realms Date: Mon, 12 Jan 2026 14:24:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=86ssc=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=A9=B1=E5=8A=A8=E5=8A=A0=E8=BD=BD=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20=E6=94=BE=E5=85=A5data//ssc=5Fanimations?= =?UTF-8?q?=EF=BC=88=E9=81=BF=E5=85=8D=E4=B8=8E=E5=85=B6=E5=AE=83=E5=8A=A8?= =?UTF-8?q?=E7=94=BB=E6=A8=A1=E7=BB=84=E8=B7=AF=E5=BE=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=EF=BC=89=20=E5=B0=86=E7=A4=BA=E4=BE=8B=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E7=A1=AC=E7=BC=96=E7=A0=81=E6=B3=A8=E5=86=8C=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E4=BB=8E=E6=95=B0=E6=8D=AEjson=E4=B8=AD=E8=AF=BB=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac | 2 + .../c622617f6fabf890a00b9275cd5f643584a8a2c8 | 2 + .../resources/META-INF/accesstransformer.cfg | 1 + out/production/resources/META-INF/mods.toml | 42 + .../resources/assets/sccore/lang/en_us.json | 32 + .../resources/assets/sccore/lang/zh_cn.json | 32 + .../am_lying_to_right_lying.json | 112 ++ .../player_animation/am_stand_to_lying.json | 64 + .../player_animation/waltz_gentleman.json | 1536 ++++++++++++++++ .../sccore/player_animation/waltz_lady.json | 1552 +++++++++++++++++ out/production/resources/logo.png | Bin 0 -> 5712 bytes out/production/resources/pack.mcmeta | 6 + out/production/resources/sccore.mixins.json | 20 + .../2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac | 4 +- .../61acbbbaada2083c247adc1ae9d8e917cd10f737 | 3 + .../c622617f6fabf890a00b9275cd5f643584a8a2c8 | 4 +- .../e2498d4cca70fa6756057cb576783dab07d8a759 | 2 + .../resources/assets/sccore/lang/en_us.json | 2 +- .../resources/assets/sccore/lang/zh_cn.json | 2 +- .../scc_animations/animation.layer.json | 6 + .../scc_animations/waltz_gentleman.anim.json | 25 + .../scc_animations/waltz_lady.anim.json | 20 + .../data/util/SCCAnimationLayerProvider.java | 172 ++ .../data/util/SCCAnimationProvider.java | 170 ++ .../event/server/ResourceReloadListener.java | 17 + .../animation/register/AnimationRegistry.java | 583 +++++-- .../sccore/core/datagen/DataGenEvent.java | 4 + .../provider/ModAnimationLayerProvider.java | 20 + .../provider/ModAnimationProvider.java | 39 + .../example/animation/ModAnimation.java | 28 +- 30 files changed, 4340 insertions(+), 162 deletions(-) create mode 100644 out/production/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac create mode 100644 out/production/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 create mode 100644 out/production/resources/META-INF/accesstransformer.cfg create mode 100644 out/production/resources/META-INF/mods.toml create mode 100644 out/production/resources/assets/sccore/lang/en_us.json create mode 100644 out/production/resources/assets/sccore/lang/zh_cn.json create mode 100644 out/production/resources/assets/sccore/player_animation/am_lying_to_right_lying.json create mode 100644 out/production/resources/assets/sccore/player_animation/am_stand_to_lying.json create mode 100644 out/production/resources/assets/sccore/player_animation/waltz_gentleman.json create mode 100644 out/production/resources/assets/sccore/player_animation/waltz_lady.json create mode 100644 out/production/resources/logo.png create mode 100644 out/production/resources/pack.mcmeta create mode 100644 out/production/resources/sccore.mixins.json create mode 100644 src/generated/resources/.cache/61acbbbaada2083c247adc1ae9d8e917cd10f737 create mode 100644 src/generated/resources/.cache/e2498d4cca70fa6756057cb576783dab07d8a759 create mode 100644 src/generated/resources/data/sccore/scc_animations/animation.layer.json create mode 100644 src/generated/resources/data/sccore/scc_animations/waltz_gentleman.anim.json create mode 100644 src/generated/resources/data/sccore/scc_animations/waltz_lady.anim.json create mode 100644 src/main/java/com/linearpast/sccore/animation/data/util/SCCAnimationLayerProvider.java create mode 100644 src/main/java/com/linearpast/sccore/animation/data/util/SCCAnimationProvider.java create mode 100644 src/main/java/com/linearpast/sccore/animation/event/server/ResourceReloadListener.java create mode 100644 src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationLayerProvider.java create mode 100644 src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationProvider.java diff --git a/out/production/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac b/out/production/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac new file mode 100644 index 0000000..afd6be6 --- /dev/null +++ b/out/production/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac @@ -0,0 +1,2 @@ +// 1.20.1 2025-11-28T18:32:27.7132485 Languages: zh_cn +33a56369fb517ec3b528128539e1e160666d9602 assets/sccore/lang/zh_cn.json diff --git a/out/production/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/out/production/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 new file mode 100644 index 0000000..9af5879 --- /dev/null +++ b/out/production/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -0,0 +1,2 @@ +// 1.20.1 2025-11-28T18:32:27.715234 Languages: en_us +941682565bf7998e144253f88be175d198e43566 assets/sccore/lang/en_us.json diff --git a/out/production/resources/META-INF/accesstransformer.cfg b/out/production/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..a6d0e63 --- /dev/null +++ b/out/production/resources/META-INF/accesstransformer.cfg @@ -0,0 +1 @@ +public net.minecraft.client.Camera f_90552_ # position \ No newline at end of file diff --git a/out/production/resources/META-INF/mods.toml b/out/production/resources/META-INF/mods.toml new file mode 100644 index 0000000..20ff457 --- /dev/null +++ b/out/production/resources/META-INF/mods.toml @@ -0,0 +1,42 @@ +modLoader = "javafml" +loaderVersion = "${loader_version_range}" +license = "${mod_license}" +issueTrackerURL="${mod_url}" + +[[mods]] +modId = "${mod_id}" +version = "${mod_version}" +displayName = "${mod_name}" +displayURL="${mod_url}" +logoFile="logo.png" +credits="${mod_credits}" +authors = "${mod_authors}" +description = '''${mod_description}''' + +[[dependencies."${mod_id}"]] +modId = "forge" +mandatory = true +versionRange = "${forge_version_range}" +ordering = "NONE" +side = "BOTH" + +[[dependencies."${mod_id}"]] +modId = "minecraft" +mandatory = true +versionRange = "${minecraft_version_range}" +ordering = "NONE" +side = "BOTH" + +[[dependencies."${mod_id}"]] +modId = "playeranimator" +mandatory = false +versionRange = "[1.0.1,)" +ordering = "AFTER" +side = "BOTH" + +[[dependencies."${mod_id}"]] +modId = "bendylib" +mandatory = false +versionRange = "[4.0.0,)" +ordering = "AFTER" +side = "BOTH" \ No newline at end of file diff --git a/out/production/resources/assets/sccore/lang/en_us.json b/out/production/resources/assets/sccore/lang/en_us.json new file mode 100644 index 0000000..dafce58 --- /dev/null +++ b/out/production/resources/assets/sccore/lang/en_us.json @@ -0,0 +1,32 @@ +{ + "translation.sccore.command.animation.accept_apply_success": "%s has accepted the application of %s.", + "translation.sccore.command.animation.accept_invite_success": "Invitation accepted.", + "translation.sccore.command.animation.accept_message_click": "Click here to accept.", + "translation.sccore.command.animation.accept_request_success": "Request accepted.", + "translation.sccore.command.animation.animation_cooldown": "You cannot perform this operation: Cooling down (%s second(s)).", + "translation.sccore.command.animation.animation_expire": "You cannot perform this operation: It has expired.", + "translation.sccore.command.animation.animation_json_path": "%s", + "translation.sccore.command.animation.animation_operation_cancelled": "Exception: Operation cancelled.", + "translation.sccore.command.animation.animation_operation_unsupported": "Error: Unsupported operation.", + "translation.sccore.command.animation.animation_out_range": "You cannot perform this operation: The distance is not within %s blocks.", + "translation.sccore.command.animation.animation_resource_not_found": "Error: Resource not found, please check if there are any errors in the resource or operation.", + "translation.sccore.command.animation.animation_to_json": "The animation %s has been stored in the path on %s:", + "translation.sccore.command.animation.applied_join_message": "%S§b§l Apply for §r to join your animation. ", + "translation.sccore.command.animation.apply_join_message": "Application sent.", + "translation.sccore.command.animation.apply_success": "%s has accepted your animation application.", + "translation.sccore.command.animation.clear_animations": "Animation cleared.", + "translation.sccore.command.animation.command_run_fail": "Command run fail.", + "translation.sccore.command.animation.command_run_success": "Command run success.", + "translation.sccore.command.animation.invite_message": "Invitation sent.", + "translation.sccore.command.animation.invite_success": "%s has accepted your animation invitation.", + "translation.sccore.command.animation.invited_message": "%s§c§l invites§r you to animation: %s. ", + "translation.sccore.command.animation.list_animation_resource": "The %2$s on %1$s has : %s", + "translation.sccore.command.animation.play_animation_fail": "Fail to play animation with: %s", + "translation.sccore.command.animation.play_animation_success": "Successfully played animation on %s player(s).", + "translation.sccore.command.animation.refresh_animations": "Animation refreshed.", + "translation.sccore.command.animation.remove_animation_fail": "Fail to remove animation with: %s", + "translation.sccore.command.animation.remove_animation_success": "Successfully removed animation on %s player(s).", + "translation.sccore.command.animation.request_message": "Request sent.", + "translation.sccore.command.animation.request_success": "%s has accepted your animation request.", + "translation.sccore.command.animation.requested_message": "%s§d§l requests§r you to animation: %s. " +} \ No newline at end of file diff --git a/out/production/resources/assets/sccore/lang/zh_cn.json b/out/production/resources/assets/sccore/lang/zh_cn.json new file mode 100644 index 0000000..9556549 --- /dev/null +++ b/out/production/resources/assets/sccore/lang/zh_cn.json @@ -0,0 +1,32 @@ +{ + "translation.sccore.command.animation.accept_apply_success": "%s 接受了 %s 的申请。", + "translation.sccore.command.animation.accept_invite_success": "已接受邀请。", + "translation.sccore.command.animation.accept_message_click": "单击此处同意。", + "translation.sccore.command.animation.accept_request_success": "已接受请求。", + "translation.sccore.command.animation.animation_cooldown": "你不能执行该操作: 冷却中(%s秒)。", + "translation.sccore.command.animation.animation_expire": "你不能执行该操作: 已过期。", + "translation.sccore.command.animation.animation_json_path": "%s", + "translation.sccore.command.animation.animation_operation_cancelled": "异常: 操作被取消。", + "translation.sccore.command.animation.animation_operation_unsupported": "错误: 不支持这样做。", + "translation.sccore.command.animation.animation_out_range": "你不能执行该操作: 距离不在%s格以内。", + "translation.sccore.command.animation.animation_resource_not_found": "错误: 资源未找到,请检查资源或操作是否有误。", + "translation.sccore.command.animation.animation_to_json": "动画%s已经存储到%s路径:", + "translation.sccore.command.animation.applied_join_message": "%s§b§l 申请§r加入动画。", + "translation.sccore.command.animation.apply_join_message": "已发送申请。", + "translation.sccore.command.animation.apply_success": "%s 接受了你的动画申请。", + "translation.sccore.command.animation.clear_animations": "动画已清除。", + "translation.sccore.command.animation.command_run_fail": "命令执行失败。", + "translation.sccore.command.animation.command_run_success": "命令执行成功。", + "translation.sccore.command.animation.invite_message": "已发送邀请。", + "translation.sccore.command.animation.invite_success": "%s 接受了你的动画邀请。", + "translation.sccore.command.animation.invited_message": "%s§c§l 邀请§r你进行动画:%s。", + "translation.sccore.command.animation.list_animation_resource": "%s侧的%s有:%s", + "translation.sccore.command.animation.play_animation_fail": "在这些玩家上播放动画失败:%s", + "translation.sccore.command.animation.play_animation_success": "在%s个玩家上播放动画成功。", + "translation.sccore.command.animation.refresh_animations": "动画同步状态已刷新。", + "translation.sccore.command.animation.remove_animation_fail": "在这些玩家上移除动画失败:%s", + "translation.sccore.command.animation.remove_animation_success": "在%s个玩家上移除动画成功。", + "translation.sccore.command.animation.request_message": "已发送请求。", + "translation.sccore.command.animation.request_success": "%s 接受了你的动画请求。", + "translation.sccore.command.animation.requested_message": "%s§d§l 请求§r你进行动画:%s。" +} \ No newline at end of file diff --git a/out/production/resources/assets/sccore/player_animation/am_lying_to_right_lying.json b/out/production/resources/assets/sccore/player_animation/am_lying_to_right_lying.json new file mode 100644 index 0000000..b3562b3 --- /dev/null +++ b/out/production/resources/assets/sccore/player_animation/am_lying_to_right_lying.json @@ -0,0 +1,112 @@ +{ + "name": "am_lying_to_right_lying", + "author": "LostInLinearPast", + "description": "fix in 1.20.1 from CreatorGalaxy", + "emote":{ + "isLoop": "false", + "returnTick": 2, + "beginTick":0, + "endTick":6, + "stopTick":2147483647, + "degrees":false, + "moves":[ + + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":-0.08066412806510925 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":-0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":-1.568853497505188 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":1.5707963705062866 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":1.5704461336135864 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.623153030872345 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.4366978108882904 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.0 + } + } + ] + } +} \ No newline at end of file diff --git a/out/production/resources/assets/sccore/player_animation/am_stand_to_lying.json b/out/production/resources/assets/sccore/player_animation/am_stand_to_lying.json new file mode 100644 index 0000000..5c753ec --- /dev/null +++ b/out/production/resources/assets/sccore/player_animation/am_stand_to_lying.json @@ -0,0 +1,64 @@ +{ + "name": "am_stand_to_lying", + "author": "LostInLinearPast", + "description": "fix in 1.20.1 from CreatorGalaxy", + "emote":{ + "isLoop": "false", + "returnTick": 2, + "beginTick":0, + "endTick":5, + "stopTick":2147483647, + "degrees":false, + "moves":[ + + { + "tick":5, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":0.0 + } + }, + { + "tick":5, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":-0.0 + } + }, + { + "tick":5, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":1.5707963705062866 + } + }, + { + "tick":5, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.623153030872345 + } + }, + { + "tick":5, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":5, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.0 + } + } + ] + } +} \ No newline at end of file diff --git a/out/production/resources/assets/sccore/player_animation/waltz_gentleman.json b/out/production/resources/assets/sccore/player_animation/waltz_gentleman.json new file mode 100644 index 0000000..2ae3908 --- /dev/null +++ b/out/production/resources/assets/sccore/player_animation/waltz_gentleman.json @@ -0,0 +1,1536 @@ +{ + "name": "waltz_gentleman", + "author": "LostInLinearPast", + "description": "waltz gentleman", + "emote":{ + "isLoop": "true", + "returnTick": 2, + "beginTick":0, + "endTick":81, + "stopTick":2147483647, + "degrees":false, + "moves":[ + + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "y":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "y":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "z":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "z":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "x":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "x":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "yaw":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "yaw":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "roll":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "roll":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "pitch":-0.1944645792245865 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "pitch":-0.1944645792245865 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":-0.06981316953897476 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.03490658476948738 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":-0.03490658476948738 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.0625 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.027499999850988388 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.009999999776482582 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.02500000037252903 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.0625 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.027499999850988388 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.009999999776482582 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.02500000037252903 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.012500000186264515 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.05000000074505806 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.13750000298023224 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.3125 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.3125 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.30000001192092896 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.26249998807907104 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.17499999701976776 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.4124999940395355 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.6875 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.7950000166893005 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.925000011920929 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.925000011920929 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.512499988079071 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.23749999701976776 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.12999999523162842 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "yaw":-0.30647698044776917 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "yaw":-0.30647698044776917 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "roll":1.3770651817321777 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "roll":1.3770651817321777 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "y":3.5131139755249023 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "y":3.5131139755249023 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "z":-0.9560732841491699 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "z":-0.9560732841491699 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "x":-5.65712833404541 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "x":-5.65712833404541 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "pitch":-1.2955334186553955 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "pitch":-1.2955334186553955 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "bend":-0.46759316325187683 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "bend":-0.46759316325187683 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "roll":-0.5759586691856384 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "roll":-0.5759586691856384 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "yaw":-1.3089969158172607 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "yaw":-1.3089969158172607 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "pitch":-1.0646508932113647 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "pitch":-1.0646508932113647 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "y":2.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "z":-1.2999999523162842 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "z":-1.2999999523162842 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "x":5.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.09413255006074905 + } + }, + { + "tick":32, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.05712477117776871 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":0.006151077337563038 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":0.010275216773152351 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.032113973051309586 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.10115855187177658 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.23402659595012665 + } + }, + { + "tick":32, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.42213836312294006 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.0634104534983635 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.1390521377325058 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.2702104151248932 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.2626937925815582 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.7774391174316406 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.2324778437614441 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":0.2255288064479828 + } + }, + { + "tick":32, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":0.1099814623594284 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":44, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.19448231160640717 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.6989269852638245 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.176431804895401 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":0.11157336086034775 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":4.2785497367248126e-11 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":4.2785497367248126e-11 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.140909433364868 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":-0.8861581921577454 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.33404916524887085 + } + }, + { + "tick":12, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.2565633952617645 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.20696492493152618 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.042693521827459335 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.10096975415945053 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.07553856074810028 + } + }, + { + "tick":10, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.1206885427236557 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0923948809504509 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.10970524698495865 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.010996125638484955 + } + }, + { + "tick":72, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.04013187810778618 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.16261258721351624 + } + }, + { + "tick":10, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.23268601298332214 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.15703840553760529 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.246794655919075 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.14305073022842407 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.2745340168476105 + } + }, + { + "tick":72, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.4361734688282013 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":6, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.5139611959457397 + } + }, + { + "tick":10, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.22671326994895935 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.08939548581838608 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.13704152405261993 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.4427417814731598 + } + }, + { + "tick":50, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.28025344014167786 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.20064905285835266 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.04128774628043175 + } + }, + { + "tick":72, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.10648827999830246 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":50, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.10896075647324324 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":0.2722991406917572 + } + }, + { + "tick":18, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":0.15728268027305603 + } + }, + { + "tick":26, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":0.17915907502174377 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + } + ] + } +} \ No newline at end of file diff --git a/out/production/resources/assets/sccore/player_animation/waltz_lady.json b/out/production/resources/assets/sccore/player_animation/waltz_lady.json new file mode 100644 index 0000000..1003640 --- /dev/null +++ b/out/production/resources/assets/sccore/player_animation/waltz_lady.json @@ -0,0 +1,1552 @@ +{ + "name": "waltz_lady", + "author": "LostInLinearPast", + "description": "waltz lady", + "emote":{ + "isLoop": "true", + "returnTick": 2, + "beginTick":0, + "endTick":81, + "stopTick":2147483647, + "degrees":false, + "moves":[ + + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "y":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "z":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "x":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "yaw":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "roll":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "pitch":0.1185886561870575 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "head":{ + "pitch":0.1185886561870575 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":3.1415927410125732 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":3.1415927410125732 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "yaw":3.1415927410125732 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "roll":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.03490658476948738 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":-0.03490658476948738 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "pitch":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.027499999850988388 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.009999999776482582 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.02500000037252903 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.0625 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.027499999850988388 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.009999999776482582 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":-0.02500000037252903 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "y":0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.012500000186264515 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.05000000074505806 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.13750000298023224 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.3125 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.3125 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.30000001192092896 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.26249998807907104 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":-0.17499999701976776 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "x":0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.5 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.9125000238418579 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-1.1875 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-1.2949999570846558 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-1.4249999523162842 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-1.4249999523162842 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-1.0125000476837158 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.737500011920929 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.6299999952316284 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.5 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.5 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "torso":{ + "z":-0.5 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "yaw":1.3089969158172607 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "yaw":1.3089969158172607 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "roll":0.5759586691856384 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "roll":0.5759586691856384 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "y":2.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "z":-1.2999999523162842 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "z":-1.2999999523162842 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "x":-5.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "pitch":-1.0646508932113647 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightArm":{ + "pitch":-1.0646508932113647 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "roll":1.510741949081421 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "roll":1.510741949081421 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "yaw":0.24142970144748688 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "yaw":0.24142970144748688 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "pitch":-1.8961212635040283 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "pitch":-1.8961212635040283 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "y":1.3259220123291016 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "y":1.3259220123291016 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "z":-0.8563777208328247 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "z":-0.8563777208328247 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "x":5.7146406173706055 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "x":5.7146406173706055 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "bend":0.37502986192703247 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftArm":{ + "bend":0.37502986192703247 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.006303687114268541 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.007730656303465366 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":0.0030700149945914745 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.030118120834231377 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "yaw":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.21962174773216248 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.2617029547691345 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.08802766352891922 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.2535526156425476 + } + }, + { + "tick":72, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":0.40923434495925903 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "roll":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":2, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.2701720595359802 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.7349715828895569 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0006949927774257958 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.00104520411696285 + } + }, + { + "tick":35, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.6743449568748474 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.15383221209049225 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":0.12758493423461914 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "pitch":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":2, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.342857241630554 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.75428593158722 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.473965883255005 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "y":12.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":2, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":-0.17428531646728515 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":-0.6542854547500611 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":-0.25547447204589846 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "z":0.1 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":2, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.20577150583267212 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.5501528382301331 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.2617993950843811 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":0.35444632172584534 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "rightLeg":{ + "bend":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":0.008380268700420856 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":0.020489023998379707 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":0.03528726473450661 + } + }, + { + "tick":32, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":0.09650745987892151 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.06075865775346756 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.03179699555039406 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":0.01990862935781479 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "yaw":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":0.0 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.04884415119886398 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.10059066116809845 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.26200801134109497 + } + }, + { + "tick":32, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.4258441925048828 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.028214696794748306 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.20640932023525238 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.21954356133937836 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.24775296449661255 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "roll":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.4414220154285431 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.18329083919525146 + } + }, + { + "tick":20, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.052891556173563004 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.08107911050319672 + } + }, + { + "tick":32, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.06880011409521103 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.636621356010437 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.05537297576665878 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.16388186812400818 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":0.03859478235244751 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "pitch":-0.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.425536721944809 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":60, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":11.753142833709717 + } + }, + { + "tick":75, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "y":12.0 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":25, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.49681914448738096 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "z":-0.1 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "x":1.9 + } + }, + { + "tick":1, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":8, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":0.20332171022891998 + } + }, + { + "tick":15, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":41, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":48, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":0.2600111663341522 + } + }, + { + "tick":55, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":0.13962633907794952 + } + }, + { + "tick":65, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + }, + { + "tick":81, + "easing": "EASEINOUTQUAD", + "turn": 0, + "leftLeg":{ + "bend":-0.0 + } + } + ] + } +} \ No newline at end of file diff --git a/out/production/resources/logo.png b/out/production/resources/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2ddf3e34a99cd71082c679ad86851a3fc97ae8b6 GIT binary patch literal 5712 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 run(@NotNull CachedOutput output) { + // Create layer data + Map layers = createLayerData().build(); + + // Convert to JSON array + JsonArray jsonArray = createJsonArray(layers); + + // Save file + Path outputPath = getOutputPath(); + + try { + return DataProvider.saveStable(output, jsonArray, outputPath); + } catch (Exception e) { + SnowyCrescentCore.log.error("Failed to save animation layer data", e); + return CompletableFuture.failedFuture(e); + } + } + + /** + * Create layer data + * Define all animation layers and their priorities here + * + * @return Map of layer ResourceLocations to priority values Builder + */ + protected abstract LayerBuilder createLayerData(); + + /** + * Convert layer data to JSON array format compatible with AnimLayerJson + * + * @param layers Layer data map + * @return JSON array representation + */ + private JsonArray createJsonArray(Map layers) { + return getJsonElements(layers); + } + + /** + * Get output path for layer configuration file + * Path: data//scc_animations/animation.layer.json + * + * @return Full output path + */ + private Path getOutputPath() { + return generator.getPackOutput().getOutputFolder() + .resolve("data") + .resolve(modId) + .resolve("scc_animations") + .resolve("animation.layer.json"); + } + + @Override + public @NotNull String getName() { + return "Animation Layer Data: " + modId; + } + + /** + * Helper class for building animation layer data + * Provides fluent API for creating layer configurations + */ + public static class LayerBuilder { + private final Map layers = new LinkedHashMap<>(); + + /** + * Create layer builder + * + */ + public static LayerBuilder create() { + return new LayerBuilder(); + } + /** + * Constructor for layer builder + * + */ + private LayerBuilder() {} + + /** + * Add a base layer with specified priority + * + * @param name Layer name + * @param priority Priority value (lower numbers = higher priority) + * @return LayerBuilder instance for chaining + */ + public LayerBuilder addBaseLayer(ResourceLocation name, int priority) { + layers.put(name, priority); + return this; + } + + /** + * Add a custom layer with specified priority + * + * @param name Layer name + * @param priority Priority value (lower numbers = higher priority) + * @return LayerBuilder instance for chaining + */ + public LayerBuilder addCustomLayer(ResourceLocation name, int priority) { + layers.put(name, priority); + return this; + } + + /** + * Build the layer map + * + * @return Unmodifiable map of layers + */ + public Map build() { + return new LinkedHashMap<>(layers); + } + + /** + * Build JSON array representation + * + * @return JSON array of layers + */ + public JsonArray buildJsonArray() { + return getJsonElements(layers); + } + } + /** + * Convert layer map to JSON array + * Layers are sorted by priority (ascending) + * + * @param layers Layer data map + * @return JSON array representation + */ + @NotNull + static JsonArray getJsonElements(Map layers) { + JsonArray jsonArray = new JsonArray(); + + layers.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEachOrdered(entry -> { + JsonObject layerObject = new JsonObject(); + layerObject.addProperty("key", entry.getKey().toString()); + layerObject.addProperty("priority", entry.getValue()); + jsonArray.add(layerObject); + }); + + return jsonArray; + } +} \ No newline at end of file diff --git a/src/main/java/com/linearpast/sccore/animation/data/util/SCCAnimationProvider.java b/src/main/java/com/linearpast/sccore/animation/data/util/SCCAnimationProvider.java new file mode 100644 index 0000000..39b2de8 --- /dev/null +++ b/src/main/java/com/linearpast/sccore/animation/data/util/SCCAnimationProvider.java @@ -0,0 +1,170 @@ +/* + * * + * * Copyright (c) 2026 R3944Realms. All rights reserved. + * * + * * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ + * * or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + * * + * * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * + */ + +package com.linearpast.sccore.animation.data.util; + +import com.google.gson.JsonObject; +import com.linearpast.sccore.animation.data.GenericAnimationData; +import com.linearpast.sccore.animation.data.Ride; +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.DataProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +/** + * Abstract base class for animation data providers + * Handles generation of animation JSON files in the scc_animations directory + */ +public abstract class SCCAnimationProvider implements DataProvider { + private final DataGenerator generator; + private final String modId; + + /** + * Constructor for animation provider + * + * @param generator Data generator instance + * @param modId Mod ID for namespace + */ + protected SCCAnimationProvider(DataGenerator generator, String modId) { + this.generator = generator; + this.modId = modId; + } + + @Override + public @NotNull CompletableFuture run(@NotNull CachedOutput output) { + List> futures = new ArrayList<>(); + Path outputFolder = generator.getPackOutput().getOutputFolder(); + + // Register animations and save them as JSON files + registerAnimations(animation -> { + ResourceLocation key = animation.getKey(); + Path path = outputFolder + .resolve("data") + .resolve(key.getNamespace()) + .resolve("scc_animations") + .resolve(key.getPath() + ".anim.json"); + + JsonObject json = convertToJson(animation); + + futures.add(DataProvider.saveStable(output, json, path)); + }); + + return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + } + + @Override + public @NotNull String getName() { + return "Animations: " + modId; + } + + /** + * Register animations to be generated + * Implement this method to define which animations to create + * + * @param consumer Consumer that accepts GenericAnimationData instances + */ + protected abstract void registerAnimations(Consumer consumer); + + /** + * Convert GenericAnimationData to JSON object + * + * @param animation Animation data to convert + * @return JSON object representation + */ + private JsonObject convertToJson(GenericAnimationData animation) { + JsonObject json = getJsonObject(animation); + + // Add camera position offset if present + Vec3 camOffset = animation.getCamPosOffset(); + if (!camOffset.equals(Vec3.ZERO) || animation.isCamPosOffsetRelative()) { + JsonObject camOffsetJson = new JsonObject(); + camOffsetJson.addProperty("x", camOffset.x); + camOffsetJson.addProperty("y", camOffset.y); + camOffsetJson.addProperty("z", camOffset.z); + camOffsetJson.addProperty("relative", animation.isCamPosOffsetRelative()); + json.add("camPosOffset", camOffsetJson); + } + + // Add ride configuration if present + Ride ride = animation.getRide(); + if (ride != null) { + JsonObject rideJson = new JsonObject(); + + JsonObject offsetJson = new JsonObject(); + Vec3 offset = ride.getOffset(); + offsetJson.addProperty("x", offset.x); + offsetJson.addProperty("y", offset.y); + offsetJson.addProperty("z", offset.z); + rideJson.add("offset", offsetJson); + + rideJson.addProperty("xRot", ride.getXRot()); + rideJson.addProperty("yRot", ride.getYRot()); + rideJson.addProperty("existTick", ride.getExistTick()); + + if (!ride.getComponentAnimations().isEmpty()) { + com.google.gson.JsonArray componentsArray = new com.google.gson.JsonArray(); + ride.getComponentAnimations().forEach(component -> + componentsArray.add(component.toString()) + ); + rideJson.add("componentsAnimation", componentsArray); + } + + json.add("withRide", rideJson); + } + + return json; + } + + /** + * Create base JSON object with common animation properties + * + * @param animation Animation data + * @return Base JSON object + */ + private static @NotNull JsonObject getJsonObject(GenericAnimationData animation) { + JsonObject json = new JsonObject(); + ResourceLocation key = animation.getKey(); + json.addProperty("key", key.toString()); + + if (animation.getName() != null) { + json.addProperty("name", animation.getName()); + } + + if (animation.getLyingType() != null) { + json.addProperty("lyingType", animation.getLyingType().getName()); + } + + json.addProperty("heightModifier", animation.getHeightModifier()); + json.addProperty("priority", animation.getCamComputePriority()); + + if (animation.getCamPitch() != 0) { + json.addProperty("camPitch", animation.getCamPitch()); + } + + if (animation.getCamRoll() != 0) { + json.addProperty("camRoll", animation.getCamRoll()); + } + + if (animation.getCamYaw() != 0) { + json.addProperty("camYaw", animation.getCamYaw()); + } + return json; + } +} \ No newline at end of file diff --git a/src/main/java/com/linearpast/sccore/animation/event/server/ResourceReloadListener.java b/src/main/java/com/linearpast/sccore/animation/event/server/ResourceReloadListener.java new file mode 100644 index 0000000..82c570e --- /dev/null +++ b/src/main/java/com/linearpast/sccore/animation/event/server/ResourceReloadListener.java @@ -0,0 +1,17 @@ +package com.linearpast.sccore.animation.event.server; + +import com.linearpast.sccore.SnowyCrescentCore; +import com.linearpast.sccore.animation.register.AnimationRegistry; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.event.AddReloadListenerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(modid = SnowyCrescentCore.MODID, value = Dist.DEDICATED_SERVER, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ResourceReloadListener { + @SubscribeEvent + public static void init (AddReloadListenerEvent event) { + event.addListener(AnimationRegistry.AnimationDataManager.INSTANCE); + event.addListener(AnimationRegistry.LayerDataManager.INSTANCE); + } +} diff --git a/src/main/java/com/linearpast/sccore/animation/register/AnimationRegistry.java b/src/main/java/com/linearpast/sccore/animation/register/AnimationRegistry.java index cdde32d..85bf5e2 100644 --- a/src/main/java/com/linearpast/sccore/animation/register/AnimationRegistry.java +++ b/src/main/java/com/linearpast/sccore/animation/register/AnimationRegistry.java @@ -1,6 +1,11 @@ package com.linearpast.sccore.animation.register; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import com.linearpast.sccore.SnowyCrescentCore; import com.linearpast.sccore.animation.capability.AnimationDataCapability; import com.linearpast.sccore.animation.capability.RawAnimationDataCapability; @@ -33,15 +38,22 @@ import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.GsonHelper; +import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.storage.LevelResource; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.AddReloadListenerEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.server.ServerStartedEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; +import javax.annotation.Nonnull; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -74,74 +86,266 @@ public class AnimationRegistry { layers.putAll(layerMap); } + @SubscribeEvent + public static void onAddReloadListeners(AddReloadListenerEvent event) { + event.addListener(AnimationDataManager.INSTANCE); + event.addListener(LayerDataManager.INSTANCE); + } + @SubscribeEvent public static void onServerStarted(ServerStartedEvent event) { - Path dataPackPath = event.getServer().getWorldPath(LevelResource.DATAPACK_DIR); + // Load legacy animations from datapacks + loadLegacyDataPackAnimations(event.getServer()); + + // Load animations from registration events + loadFromRegistrationEvents(); + + SnowyCrescentCore.log.info("Animation loading completed. Total animations: {}, Total layers: {}", + animations.size(), layers.size()); + } + + /** + * Load legacy datapack animations from world/datapacks/animation directory + */ + private static void loadLegacyDataPackAnimations(MinecraftServer server) { + Path dataPackPath = server.getWorldPath(LevelResource.DATAPACK_DIR); Path animationPath = dataPackPath.resolve("animation"); + if (!Files.exists(animationPath)) { try { Files.createDirectories(animationPath); - } catch (IOException e) { return; } - } - - FileUtils.safeUnzip(dataPackPath.resolve("animation.zip").toString(), animationPath.toAbsolutePath().toString()); - Set animZipPaths = FileUtils.getAllFile( - dataPackPath.resolve("animation"), - path -> path.toString().endsWith(".anim.zip") - ); - Set layerZipPaths = FileUtils.getAllFile( - dataPackPath.resolve("animation"), - path -> path.toString().endsWith(".layer.zip") - ); - for (Path zipPath : animZipPaths) { - FileUtils.safeUnzip(zipPath.toString(), animationPath.toAbsolutePath().toString()); - } - for (Path zipPath : layerZipPaths) { - FileUtils.safeUnzip(zipPath.toString(), animationPath.toAbsolutePath().toString()); - } - - Set animPaths = FileUtils.getAllFile( - dataPackPath.resolve("animation"), - path -> path.toString().endsWith(".anim.json") - ); - Set layerPaths = FileUtils.getAllFile( - dataPackPath.resolve("animation"), - path -> path.getFileName().toString().equals("animation.layer.json") - ); - Set animationsSet = new HashSet<>(); - Map layersMap = new HashMap<>(); - for (Path path : animPaths) { - try { - AnimJson.Reader reader = AnimJson.Reader.stream(path); - GenericAnimationData anim = reader.parse(); - animationsSet.add(anim); - } catch (Exception ignored) { - SnowyCrescentCore.log.error("Failed to parse animation JSON: {}", path.toString()); - } - } - for (Path path : layerPaths) { - try { - AnimLayerJson.Reader reader = AnimLayerJson.Reader.stream(path); - Map parse = reader.parse(); - layersMap.putAll(parse); - } catch (Exception ignored) { - SnowyCrescentCore.log.error("Failed to parse layer JSON: {}", path.toString()); + } catch (IOException e) { + SnowyCrescentCore.log.error("Failed to create legacy animation directory", e); + return; } } - animations.clear(); + try { + // Handle zip files + if (Files.exists(dataPackPath.resolve("animation.zip"))) { + FileUtils.safeUnzip(dataPackPath.resolve("animation.zip").toString(), + animationPath.toAbsolutePath().toString()); + } + + Set animZipPaths = FileUtils.getAllFile( + dataPackPath.resolve("animation"), + path -> path.toString().endsWith(".anim.zip") + ); + + Set layerZipPaths = FileUtils.getAllFile( + dataPackPath.resolve("animation"), + path -> path.toString().endsWith(".layer.zip") + ); + + for (Path zipPath : animZipPaths) { + FileUtils.safeUnzip(zipPath.toString(), animationPath.toAbsolutePath().toString()); + } + + for (Path zipPath : layerZipPaths) { + FileUtils.safeUnzip(zipPath.toString(), animationPath.toAbsolutePath().toString()); + } + + // Load animation JSON files + Set animPaths = FileUtils.getAllFile( + dataPackPath.resolve("animation"), + path -> path.toString().endsWith(".anim.json") + ); + + Set layerPaths = FileUtils.getAllFile( + dataPackPath.resolve("animation"), + path -> path.getFileName().toString().equals("animation.layer.json") + ); + + for (Path path : animPaths) { + try { + AnimJson.Reader reader = AnimJson.Reader.stream(path); + GenericAnimationData anim = reader.parse(); + animations.put(anim.getKey(), anim); + SnowyCrescentCore.log.info("Loaded legacy animation: {} -> {}", + anim.getKey(), anim.getName()); + } catch (Exception e) { + SnowyCrescentCore.log.error("Failed to parse legacy animation JSON: {}", path, e); + } + } + + for (Path path : layerPaths) { + try { + AnimLayerJson.Reader reader = AnimLayerJson.Reader.stream(path); + Map parse = reader.parse(); + layers.putAll(parse); + SnowyCrescentCore.log.info("Loaded {} legacy layer configurations from {}", + parse.size(), path); + } catch (Exception e) { + SnowyCrescentCore.log.error("Failed to parse legacy layer JSON: {}", path, e); + } + } + } catch (Exception e) { + SnowyCrescentCore.log.error("Error loading legacy animations", e); + } + } + + /** + * Load animations from registration events + */ + private static void loadFromRegistrationEvents() { AnimationRegisterEvent.Animation animationRegisterEvent = new AnimationRegisterEvent.Animation(); MinecraftForge.EVENT_BUS.post(animationRegisterEvent); Map animationMap = animationRegisterEvent.getAnimations(); animations.putAll(animationMap); - animations.putAll(animationsSet.stream().collect(Collectors.toMap(GenericAnimationData::getKey, animation -> animation))); - layers.clear(); AnimationRegisterEvent.Layer layerRegisterEvent = new AnimationRegisterEvent.Layer(); MinecraftForge.EVENT_BUS.post(layerRegisterEvent); Map layerMap = layerRegisterEvent.getLayers(); layers.putAll(layerMap); - layers.putAll(layersMap); + + SnowyCrescentCore.log.info("Loaded {} animations and {} layers from registration events", + animationMap.size(), layerMap.size()); + } + + /** + * Animation data manager using SimpleJsonResourceReloadListener + */ + public static class AnimationDataManager extends SimpleJsonResourceReloadListener { + public static final AnimationDataManager INSTANCE = new AnimationDataManager(); + + private AnimationDataManager() { + super(new GsonBuilder() + .setPrettyPrinting() + .disableHtmlEscaping() + .create(), "scc_animations"); + } + + @Override + protected void apply(@Nonnull Map resources, + @Nonnull ResourceManager resourceManager, + @Nonnull ProfilerFiller profiler) { + SnowyCrescentCore.log.info("Loading animations from data packs..."); + + Map sorted = new LinkedHashMap<>(); + + // Sort resources by priority + resourceManager.listPacks().forEach(packResources -> { + Set namespaces = packResources.getNamespaces(PackType.SERVER_DATA); + namespaces.forEach(namespace -> + packResources.listResources(PackType.SERVER_DATA, namespace, "scc_animations", + (resourceLocation, inputStreamIoSupplier) -> { + String path = resourceLocation.getPath(); + if (path.endsWith(".anim.json")) { + ResourceLocation rl = new ResourceLocation(namespace, + path.substring("scc_animations/".length(), path.length() - ".json".length())); + + JsonElement el = resources.get(rl); + if (el != null) { + rl = new ResourceLocation(namespace, + path.substring("scc_animations/".length(), path.length() - ".anim.json".length())); + sorted.put(rl, el); + } + } + } + ) + ); + }); + + int loadedCount = 0; + for (Map.Entry entry : sorted.entrySet()) { + ResourceLocation animKey = entry.getKey(); + + try { + JsonObject json = GsonHelper.convertToJsonObject(entry.getValue(), "animation"); + + // Parse animation using existing AnimJson.Reader + AnimJson.Reader animReader = AnimJson.Reader.stream(json); + GenericAnimationData anim = animReader.parse(); + + // Ensure the key matches + if (!anim.getKey().equals(animKey)) { + SnowyCrescentCore.log.warn("Animation key mismatch: file={}, expected={}, actual={}", + entry.getKey(), animKey, anim.getKey()); + anim = anim.withName(animKey.getPath()); // Create a copy with correct key if possible + } + + animations.put(animKey, anim); + loadedCount++; + SnowyCrescentCore.log.debug("Loaded animation: {} -> {}", animKey, anim.getName()); + + } catch (IllegalArgumentException | JsonParseException e) { + SnowyCrescentCore.log.error("Parsing error loading animation {}", animKey, e); + } + } + + SnowyCrescentCore.log.info("Loaded {} animations from data packs", loadedCount); + } + } + + /** + * Layer data manager using SimpleJsonResourceReloadListener + */ + public static class LayerDataManager extends SimpleJsonResourceReloadListener { + public static final LayerDataManager INSTANCE = new LayerDataManager(); + + + private LayerDataManager() { + super(new GsonBuilder() + .setPrettyPrinting() + .disableHtmlEscaping() + .create(), "scc_animations"); + } + + @Override + protected void apply(@Nonnull Map resources, + @Nonnull ResourceManager resourceManager, + @Nonnull ProfilerFiller profiler) { + SnowyCrescentCore.log.info("Loading layer configurations from data packs..."); + + Map sorted = new LinkedHashMap<>(); + + // Sort resources by priority + resourceManager.listPacks().forEach(packResources -> { + Set namespaces = packResources.getNamespaces(PackType.SERVER_DATA); + namespaces.forEach(namespace -> + packResources.listResources(PackType.SERVER_DATA, namespace, "scc_animations", + (resourceLocation, inputStreamIoSupplier) -> { + String path = resourceLocation.getPath(); + if (path.endsWith("animation.layer.json")) { + ResourceLocation rl = new ResourceLocation(namespace, "animation.layer"); + + JsonElement el = resources.get(rl); + if (el != null) { + rl = new ResourceLocation(namespace, "animation_layer"); + sorted.put(rl, el); + } + } + } + ) + ); + }); + + int loadedCount = 0; + for (Map.Entry entry : sorted.entrySet()) { + try { + JsonElement json = entry.getValue(); + AnimLayerJson.Reader layerReader = AnimLayerJson.Reader.stream(json); + Map parsedLayers = layerReader.parse(); + + // Merge layer configurations + parsedLayers.forEach((layerKey, priority) -> { + if (layers.containsKey(layerKey)) { + SnowyCrescentCore.log.debug("Overriding layer {} with priority {}", layerKey, priority); + } + layers.put(layerKey, priority); + }); + + loadedCount += parsedLayers.size(); + SnowyCrescentCore.log.debug("Loaded {} layer configurations from {}", + parsedLayers.size(), entry.getKey().getNamespace()); + + } catch (IllegalArgumentException | JsonParseException e) { + SnowyCrescentCore.log.error("Parsing error loading layer configuration", e); + } + } + + SnowyCrescentCore.log.info("Loaded {} layer configurations from data packs", loadedCount); + } } @SubscribeEvent @@ -149,29 +353,64 @@ public class AnimationRegistry { if (event.getEntity() instanceof ServerPlayer serverPlayer) { MinecraftServer server = serverPlayer.getServer(); if(server == null) return; - Path dataPackPath = server.getWorldPath(LevelResource.DATAPACK_DIR); - Path animationPath = dataPackPath.resolve("animation"); - if (!Files.exists(animationPath)) { - try {Files.createDirectories(animationPath);} - catch (IOException e) { return; } - } - ModChannel.sendToPlayer(new AnimationClientStatusPacket(AnimationClientStatusPacket.Status.ANIM_CACHE_CLEAR), serverPlayer); - for (GenericAnimationData value : animations.values()) { - JsonElement json = AnimJson.Writer.stream(value).toJson(); - String string = json.toString(); - ModChannel.sendToPlayer(new AnimationJsonPacket(string, false), serverPlayer); - } - ModChannel.sendToPlayer(new AnimationClientStatusPacket(AnimationClientStatusPacket.Status.ANIM_REGISTER), serverPlayer); - ModChannel.sendToPlayer(new AnimationClientStatusPacket(AnimationClientStatusPacket.Status.LAYER_CACHE_CLEAR), serverPlayer); - Map jsonElementMap = AnimLayerJson.Writer.stream(animationPath).allToJson(); - jsonElementMap.forEach((key, value) -> - ModChannel.sendToPlayer(new AnimationJsonPacket(value.toString(), true), serverPlayer) - ); - ModChannel.sendToPlayer(new AnimationClientStatusPacket(AnimationClientStatusPacket.Status.LAYER_REGISTER), serverPlayer); - } + // Send animations to client + sendAnimationsToClient(serverPlayer); + } } + /** + * Send all animations and layers to the client + */ + private static void sendAnimationsToClient(ServerPlayer player) { + SnowyCrescentCore.log.debug("Sending animations to player: {}", player.getName().getString()); + + // Clear client cache first + ModChannel.sendToPlayer(new AnimationClientStatusPacket( + AnimationClientStatusPacket.Status.ANIM_CACHE_CLEAR), player); + + // Send all animations + for (GenericAnimationData anim : animations.values()) { + JsonElement json = AnimJson.Writer.stream(anim).toJson(); + String jsonString = json.toString(); + ModChannel.sendToPlayer(new AnimationJsonPacket(jsonString, false), player); + } + + // Register animations on client + ModChannel.sendToPlayer(new AnimationClientStatusPacket( + AnimationClientStatusPacket.Status.ANIM_REGISTER), player); + + // Clear layer cache + ModChannel.sendToPlayer(new AnimationClientStatusPacket( + AnimationClientStatusPacket.Status.LAYER_CACHE_CLEAR), player); + + // Send layer configurations + JsonElement layerJson = convertLayersToJson(layers); + ModChannel.sendToPlayer(new AnimationJsonPacket(layerJson.toString(), true), player); + + // Register layers on client + ModChannel.sendToPlayer(new AnimationClientStatusPacket( + AnimationClientStatusPacket.Status.LAYER_REGISTER), player); + + SnowyCrescentCore.log.debug("Sent {} animations and {} layers to player {}", + animations.size(), layers.size(), player.getName().getString()); + } + + /** + * Convert layers map to JSON + */ + private static JsonElement convertLayersToJson(Map layers) { + JsonArray jsonArray = new JsonArray(); + + for (Map.Entry entry : layers.entrySet()) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("key", entry.getKey().toString()); + jsonObject.addProperty("priority", entry.getValue()); + jsonArray.add(jsonObject); + } + + return jsonArray; + } @OnlyIn(Dist.CLIENT) public static class ClientCache { @@ -188,7 +427,6 @@ public class AnimationRegistry { layersCache.put(location, priority); } - @SuppressWarnings({"JavaReflectionMemberAccess", "UnstableApiUsage", "unchecked"}) public static void animationStatusUpdate(AnimationClientStatusPacket.Status status) { switch (status) { case ANIM_CACHE_CLEAR -> animationsCache.clear(); @@ -206,94 +444,155 @@ public class AnimationRegistry { registerLayers(layersCache); layersCache.forEach((key, value) -> PlayerAnimationFactory.ANIMATION_DATA_FACTORY.registerFactory( key, value, player -> { - if(Minecraft.getInstance().player == null) return ClientCache.registerPlayerAnimation(player); - Map animationMap = modifierLayers.getOrDefault(player.getUUID(), new HashMap<>()); - if(animationMap.containsKey(key)) return animationMap.get(key); + if (Minecraft.getInstance().player == null) { + return ClientCache.registerPlayerAnimation(player); + } + Map animationMap = + modifierLayers.getOrDefault(player.getUUID(), new HashMap<>()); + if (animationMap.containsKey(key)) { + return animationMap.get(key); + } IAnimation iAnimation = ClientCache.registerPlayerAnimation(player); animationMap.put(key, iAnimation); modifierLayers.put(player.getUUID(), animationMap); return iAnimation; }) ); + + // Update existing players' animation stacks ClientLevel level = Minecraft.getInstance().level; - if(level == null) { - SnowyCrescentCore.log.error("{} : Level is null", ClientCache.class.getName()); + if (level == null) { + SnowyCrescentCore.log.error("Level is null, cannot update animation layers"); return; } + try { for (AbstractClientPlayer player : level.players()) { - try { - Class playerClass = Player.class; - Field animationStackField = playerClass.getDeclaredField("animationStack"); - animationStackField.setAccessible(true); - Method createAnimationStack = playerClass.getDeclaredMethod("createAnimationStack"); - createAnimationStack.setAccessible(true); - AnimationStack newAnimationStack = (AnimationStack) createAnimationStack.invoke(player); - AnimationStack oldAnimationStack = (AnimationStack) animationStackField.get(player); - Field layersField = AnimationStack.class.getDeclaredField("layers"); - layersField.setAccessible(true); - ArrayList> oldArrayList = new ArrayList<>((ArrayList>) layersField.get(oldAnimationStack)); - ArrayList> newArrayList = new ArrayList<>((ArrayList>) layersField.get(newAnimationStack)); - ArrayList> result = new ArrayList<>(); - for (Pair oldAnimationPair : List.copyOf(oldArrayList)) { - for (Pair newAnimationPair : List.copyOf(newArrayList)) { - if(Objects.equals(oldAnimationPair.getLeft(), newAnimationPair.getLeft())) { - KeyframeAnimation oldData = Optional.ofNullable((KeyframeAnimationPlayer) ((ModifierLayer) oldAnimationPair.getRight()).getAnimation()) - .map(KeyframeAnimationPlayer::getData).orElse(null); - KeyframeAnimation newData = Optional.ofNullable((KeyframeAnimationPlayer) ((ModifierLayer) newAnimationPair.getRight()).getAnimation()) - .map(KeyframeAnimationPlayer::getData).orElse(null); - if(Objects.equals(oldData, newData)) oldArrayList.remove(oldAnimationPair); - } - } - } - result.addAll(oldArrayList); - result.addAll(newArrayList); - - layersField.set(newAnimationStack, result); - animationStackField.set(player, newAnimationStack); - Field animationApplierField = playerClass.getDeclaredField("animationApplier"); - animationApplierField.setAccessible(true); - animationApplierField.set(player, new AnimationApplier(newAnimationStack)); - IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); - if(data == null) continue; - RawAnimationDataCapability rawData = RawAnimationDataCapability.getCapability(player).orElse(null); - if(rawData == null) continue; - Map dataAnimations = new HashMap<>(); - dataAnimations.putAll(data.getAnimations()); - dataAnimations.putAll(rawData.getAnimations()); - ResourceLocation riderAnimLayer = data.getRiderAnimLayer(); - if(riderAnimLayer != null) { - dataAnimations.put(riderAnimLayer, data.getRiderAnimation()); - } - for (ResourceLocation location : dataAnimations.keySet()) { - ModifierLayer modifierLayer = (ModifierLayer) PlayerAnimationAccess - .getPlayerAssociatedData(player).get(location); - if(modifierLayer == null) continue; - KeyframeAnimation keyframeAnimation; - ResourceLocation animationLocation = dataAnimations.get(location); - GenericAnimationData anim = animations.get(animationLocation); - if(anim == null) { - RawAnimationData rawAnim = RawAnimationService.INSTANCE.getAnimation(animationLocation); - if(rawAnim == null) return; - keyframeAnimation = rawAnim.getAnimation(); - } else keyframeAnimation = anim.getAnimation(); - if(keyframeAnimation == null) continue; - modifierLayer.replaceAnimationWithFade( - AbstractFadeModifier.standardFadeIn(3, Ease.INOUTSINE), - new KeyframeAnimationPlayer(keyframeAnimation) - ); - } - }catch (Exception e){ - SnowyCrescentCore.log.error("Failed to register on {} animation layer: {}", player, e.getMessage(), e); - } + updatePlayerAnimationStack(player); } - } catch (Exception ignored) {} + } catch (Exception e) { + SnowyCrescentCore.log.error("Failed to update player animation layers", e); + } } } } + /** + * Update a player's animation stack with new layers + */ + @SuppressWarnings({"unchecked", "JavaReflectionMemberAccess"}) + private static void updatePlayerAnimationStack(AbstractClientPlayer player) { + try { + Class playerClass = Player.class; + Field animationStackField = playerClass.getDeclaredField("animationStack"); + animationStackField.setAccessible(true); + + Method createAnimationStack = playerClass.getDeclaredMethod("createAnimationStack"); + createAnimationStack.setAccessible(true); + + AnimationStack newAnimationStack = (AnimationStack) createAnimationStack.invoke(player); + AnimationStack oldAnimationStack = (AnimationStack) animationStackField.get(player); + + Field layersField = AnimationStack.class.getDeclaredField("layers"); + layersField.setAccessible(true); + + ArrayList> oldArrayList = + new ArrayList<>((ArrayList>) layersField.get(oldAnimationStack)); + ArrayList> newArrayList = + new ArrayList<>((ArrayList>) layersField.get(newAnimationStack)); + + // Merge layers, keeping unique ones + ArrayList> result = new ArrayList<>(); + + // Add old layers that aren't replaced by new ones + for (Pair oldPair : oldArrayList) { + boolean isReplaced = false; + for (Pair newPair : newArrayList) { + if (Objects.equals(oldPair.getLeft(), newPair.getLeft())) { + isReplaced = true; + break; + } + } + if (!isReplaced) { + result.add(oldPair); + } + } + + // Add all new layers + result.addAll(newArrayList); + + // Set the merged layers + layersField.set(newAnimationStack, result); + animationStackField.set(player, newAnimationStack); + + // Update animation applier + Field animationApplierField = playerClass.getDeclaredField("animationApplier"); + animationApplierField.setAccessible(true); + //noinspection UnstableApiUsage + animationApplierField.set(player, new AnimationApplier(newAnimationStack)); + + // Restore any playing animations + restorePlayingAnimations(player); + + } catch (Exception e) { + SnowyCrescentCore.log.error("Failed to update animation stack for player: {}", player, e); + } + } + + /** + * Restore animations that were playing before the update + */ + private static void restorePlayingAnimations(AbstractClientPlayer player) { + try { + IAnimationCapability data = AnimationDataCapability.getCapability(player).orElse(null); + if (data == null) return; + + RawAnimationDataCapability rawData = RawAnimationDataCapability.getCapability(player).orElse(null); + if (rawData == null) return; + + Map dataAnimations = new HashMap<>(); + dataAnimations.putAll(data.getAnimations()); + dataAnimations.putAll(rawData.getAnimations()); + + ResourceLocation riderAnimLayer = data.getRiderAnimLayer(); + if (riderAnimLayer != null && data.getRiderAnimation() != null) { + dataAnimations.put(riderAnimLayer, data.getRiderAnimation()); + } + + for (Map.Entry entry : dataAnimations.entrySet()) { + ResourceLocation layerKey = entry.getKey(); + ResourceLocation animKey = entry.getValue(); + + @SuppressWarnings("unchecked") + ModifierLayer modifierLayer = (ModifierLayer) + PlayerAnimationAccess.getPlayerAssociatedData(player).get(layerKey); + if (modifierLayer == null) continue; + + KeyframeAnimation keyframeAnimation; + GenericAnimationData anim = animations.get(animKey); + + if (anim == null) { + RawAnimationData rawAnim = RawAnimationService.INSTANCE.getAnimation(animKey); + if (rawAnim == null) continue; + keyframeAnimation = rawAnim.getAnimation(); + } else { + keyframeAnimation = anim.getAnimation(); + } + + if (keyframeAnimation == null) continue; + + modifierLayer.replaceAnimationWithFade( + AbstractFadeModifier.standardFadeIn(3, Ease.INOUTSINE), + new KeyframeAnimationPlayer(keyframeAnimation) + ); + } + } catch (Exception e) { + SnowyCrescentCore.log.error("Failed to restore playing animations for player: {}", player, e); + } + } + private static IAnimation registerPlayerAnimation(AbstractClientPlayer player) { return new ModifierLayer<>(); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/linearpast/sccore/core/datagen/DataGenEvent.java b/src/main/java/com/linearpast/sccore/core/datagen/DataGenEvent.java index b123fc2..89a2b60 100644 --- a/src/main/java/com/linearpast/sccore/core/datagen/DataGenEvent.java +++ b/src/main/java/com/linearpast/sccore/core/datagen/DataGenEvent.java @@ -1,6 +1,8 @@ package com.linearpast.sccore.core.datagen; import com.linearpast.sccore.SnowyCrescentCore; +import com.linearpast.sccore.core.datagen.provider.ModAnimationLayerProvider; +import com.linearpast.sccore.core.datagen.provider.ModAnimationProvider; import com.linearpast.sccore.core.datagen.provider.ModLangProvider; import net.minecraft.core.HolderLookup; import net.minecraft.data.DataGenerator; @@ -24,5 +26,7 @@ public class DataGenEvent { generator.addProvider(event.includeClient(), new ModLangProvider(packOutput, ModLangProvider.Lang.EN_US)); generator.addProvider(event.includeClient(), new ModLangProvider(packOutput, ModLangProvider.Lang.ZH_CN)); + generator.addProvider(true, new ModAnimationProvider(generator)); + generator.addProvider(true, new ModAnimationLayerProvider(generator)); } } diff --git a/src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationLayerProvider.java b/src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationLayerProvider.java new file mode 100644 index 0000000..c2e6357 --- /dev/null +++ b/src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationLayerProvider.java @@ -0,0 +1,20 @@ +package com.linearpast.sccore.core.datagen.provider; + +import com.linearpast.sccore.SnowyCrescentCore; + +import com.linearpast.sccore.animation.data.util.SCCAnimationLayerProvider; +import com.linearpast.sccore.example.animation.ModAnimation; +import net.minecraft.data.DataGenerator; + +public class ModAnimationLayerProvider extends SCCAnimationLayerProvider { + public ModAnimationLayerProvider(DataGenerator generator) { + super(generator, SnowyCrescentCore.MODID); + } + + + @Override + protected LayerBuilder createLayerData() { + return LayerBuilder.create() + .addCustomLayer(ModAnimation.normalLayers, 42); + } +} diff --git a/src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationProvider.java b/src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationProvider.java new file mode 100644 index 0000000..c6a4e32 --- /dev/null +++ b/src/main/java/com/linearpast/sccore/core/datagen/provider/ModAnimationProvider.java @@ -0,0 +1,39 @@ +package com.linearpast.sccore.core.datagen.provider; + +import com.linearpast.sccore.SnowyCrescentCore; +import com.linearpast.sccore.animation.data.GenericAnimationData; +import com.linearpast.sccore.animation.data.Ride; +import com.linearpast.sccore.animation.data.util.SCCAnimationProvider; +import net.minecraft.data.DataGenerator; +import net.minecraft.world.phys.Vec3; + +import java.util.function.Consumer; + +import static com.linearpast.sccore.example.animation.ModAnimation.WaltzGentleman; +import static com.linearpast.sccore.example.animation.ModAnimation.WaltzLady; + +public class ModAnimationProvider extends SCCAnimationProvider { + + public ModAnimationProvider(DataGenerator generator) { + super(generator, SnowyCrescentCore.MODID); + } + + @Override + protected void registerAnimations(Consumer consumer) { + { + GenericAnimationData waltzGentleman = (GenericAnimationData) GenericAnimationData + .create(WaltzGentleman) + .withName("Waltz-Gentleman") + .addCamPosOffset(new Vec3(0.0, 0.0, 1.0)) + .withCamPosOffsetRelative(true) + .withRide(Ride.create().addComponentAnimation(WaltzLady)); + GenericAnimationData waltzLady = (GenericAnimationData) GenericAnimationData + .create(WaltzLady) + .withName("Waltz-Lady") + .withCamYaw(180) + .withRide(Ride.create().addComponentAnimation(WaltzGentleman)); + consumer.accept(waltzGentleman); + consumer.accept(waltzLady); + } + } +} diff --git a/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java b/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java index 23521c5..a553738 100644 --- a/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java +++ b/src/main/java/com/linearpast/sccore/example/animation/ModAnimation.java @@ -38,7 +38,7 @@ public class ModAnimation { * @param event event */ public static void onLayerRegister(AnimationRegisterEvent.Layer event) { - event.registerLayer(normalLayers, 42); +// event.registerLayer(normalLayers, 42); } /** @@ -54,23 +54,23 @@ public class ModAnimation { // GenericAnimationData amSTL = GenericAnimationData.create(AmStandToLying) // .withName("Stand-to-Lying") // .withLyingType(GenericAnimationData.LyingType.FRONT); - GenericAnimationData waltzGentleman = (GenericAnimationData) GenericAnimationData - .create(WaltzGentleman) - .withName("Waltz-Gentleman") - .addCamPosOffset(new Vec3(0.0,0.0,1.0)) - .withCamPosOffsetRelative(true) - .withRide(Ride.create().addComponentAnimation(WaltzLady)); - GenericAnimationData waltzLady = (GenericAnimationData) GenericAnimationData - .create(WaltzLady) - .withName("Waltz-Lady") - .withCamYaw(180) - .withRide(Ride.create().addComponentAnimation(WaltzGentleman)); +// GenericAnimationData waltzGentleman = (GenericAnimationData) GenericAnimationData +// .create(WaltzGentleman) +// .withName("Waltz-Gentleman") +// .addCamPosOffset(new Vec3(0.0,0.0,1.0)) +// .withCamPosOffsetRelative(true) +// .withRide(Ride.create().addComponentAnimation(WaltzLady)); +// GenericAnimationData waltzLady = (GenericAnimationData) GenericAnimationData +// .create(WaltzLady) +// .withName("Waltz-Lady") +// .withCamYaw(180) +// .withRide(Ride.create().addComponentAnimation(WaltzGentleman)); //You can use it to invite an Animation // event.registerAnimation(AmLyingToRightLying, amLTRL); // event.registerAnimation(AmStandToLying, amSTL); - event.registerAnimation(WaltzGentleman, waltzGentleman); - event.registerAnimation(WaltzLady, waltzLady); +// event.registerAnimation(WaltzGentleman, waltzGentleman); +// event.registerAnimation(WaltzLady, waltzLady); } public static void onRawAnimationRegister(AnimationRegisterEvent.RawAnimation event) {