1 | --R6 animations for R15 ava without reanim! |
2 | --this is a skript that roblox made (skript lokation: content\avatar\unification\humanoidClassicAnimate.lua) but I edited for it to work with exploits and etc. |
3 | --edit by Invisible_#3657 thx nigga |
4 | --[[ |
5 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠁⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
6 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢶⣿⢃⣠⣴⣶⣶⣿⣛⢯⣹⣾⠁⠀⠀⠀⠀⠀⢀⣀⣤⣴⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀ |
7 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣻⣾⣿⣞⣯⣷⣽⣾⣿⣁⣀⣠⢤⡶⣶⠿⣻⣶⣟⡿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀ |
8 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣟⣯⣿⣶⣯⣿⣿⣿⡁⠀⣴⠿⣟⣿⣟⣿⣻⢷⢯⣞⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⢈⡇⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
9 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡶⢒⣖⣲⡶⢶⡖⣶⣒⢶⡲⣞⣫⠭⣭⣭⣽⣭⣯⣽⣿⣿⣿⣿⣿⣿⣿⠿⢿⡿⠿⠿⠿⣌⠿⢿⣿⣿⣿⣿⡾⣽⢯⣟⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠘⡀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
10 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣯⣛⢧⣛⢧⣛⡶⣹⣎⢷⣝⡮⣟⢷⡾⣹⢯⡟⠉⠉⠛⢿⣿⣿⣯⣟⣿⣫⣽⡿⣃⣔⣬⣿⣷⣯⣿⣿⣿⣿⣽⣻⣾⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
11 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣟⡾⣭⡟⣾⣹⢗⣾⣫⢾⡽⣽⢾⡽⢯⡟⠀⠀⠀⢀⢈⣿⣿⣿⣿⣿⠿⢻⣷⣼⣿⣿⣟⣿⣟⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠀⠀⠐⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
12 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣷⣿⣷⣯⣟⡾⣽⣳⢿⡽⣾⡽⡟⠀⠀⢀⣰⠞⠟⠙⢻⣷⣿⣸⣷⣾⣟⣺⣽⣟⣻⣿⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
13 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⣿⣷⣯⣿⣽⣳⢿⠃⠀⠀⢀⠀⢠⣤⣦⣄⣇⠉⠛⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
14 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠻⣿⣿⣿⣿⣿⣉⠉⠉⠻⠀⠀⠠⢀⣾⢿⠋⢁⣿⣿⠀⠀⠀⠀⣿⣧⠙⢿⣹⣏⢠⣛⠟⠁⠀⠀⢀⣴⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀ |
15 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⣿⣿⣿⣓⣈⣰⣦⣤⣀⣼⠋⠀⠀⢭⣽⣿⡇⠀⣀⣀⣿⣿⡇⡸⣿⣿⡤⠉⠒⠤⣀⠀⠠⡄⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
16 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⢹⠏⠀⠛⣞⣧⣾⠍⠢⣀⠀⠈⠻⠟⣇⢉⣡⡶⣭⠯⡀⠐⠛⠙⢇⠀⠐⢲⠏⠀⠀⠈⠲⠞⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
17 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠁⢀⠄⠂⢸⠛⠁⣠⣲⡆⢔⠾⠋⠀⠈⠢⣉⠀⢀⣀⣈⡆⠀⠀⢸⣀⠔⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀ |
18 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠚⠤⣌⡁⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⡿⠀⠀⣜⣩⠟⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
19 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⣛⡉⠀⠀⠓⢄⡀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⡹⠋⠀⣠⠞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
20 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠐⠒⠚⣿⣶⠦⣄⣀⡀⠘⠿⠽⠶⢾⣷⣀⠖⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
21 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣀⡀⣀⣀⣠⡿⠍⣛⠻⡿⠿⣟⣲⣶⣶⡶⠿⣿⣖⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
22 | ⠀⠀⠀⠀⠀⠀⠀⠀⣠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠼⠛⢻⠿⠻⢿⣿⣷⣿⣶⣆⠬⡯⣑⣿⣿⣿⣿⣹⣍⣧⣾⠈⠉⠉⠒⠒⠠⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
23 | ⠀⠀⠀⠀⠀⠀⠀⢠⠁⢡⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠋⠀⠀⠐⠒⠠⣔⠁⠀⠉⣿⣿⣿⢛⡖⠾⠿⢿⡿⠿⣾⠟⠁⠀⠀⠀⠀⠀⠸⠀⠱⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
24 | ⠀⠀⠀⠀⠀⠀⢠⠃⠀⠀⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⡅⠀⠀⠀⠀⠀⠀⠀⠉⠒⠄⠘⢿⣿⠇⠈⠁⠒⠺⣤⣢⡼⠀⠀⠀⠀⠀⠀⠀⠸⠀⠀⠘⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
25 | ⠀⠀⠀⠀⠀⠀⠣⡀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠹⡄⠐⠒⠠⠤⠀⣀⠀⠀⠀⠀⠈⣏⠀⠀⠀⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⢆⠀⠀⠙⣆⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
26 | ⠀⠀⠀⠀⠀⠀⠀⠑⣄⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠘⣆⠀⠀⠀⠀⠀⠉⠑⠢⡀⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
27 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⠀⠈⢣⡀⠠⢄⣀⠀⠀⠀⢠⠞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
28 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠧⣀⣀⠀⢀⡤⠋⠀⠀⠀⠀⠈⢁⠒⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡆⠀⢀⣠⢾⡍⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠆⠈⢂⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
29 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠞⣻⡿⠏⠀⠀⠀⠐⠢⠄⢀⡀⣰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡷⠖⠋⣁⡼⣇⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⡀⢀⡎⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀ |
30 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⡔⠍⠀⠀⠈⠢⣀⠀⠀⠀⡰⢠⡇⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⡴⠋⠁⠁⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⡴⠁⠀⠀⠀⠀⠀⠀⠀⠀ |
31 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢧⠄⠂⡄⠀⠀⠀⠀⠁⠢⢴⣁⡼⠀⠀⠀⠈⠑⠂⠀⠤⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣧⣀⠤⠖⠉⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
32 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⢠⠀⠀⠀⠑⠤⡀⠀⠀⡐⠁⢰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
33 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠈⢆⠀⠀⠀⠀⠀⢑⠞⠤⣠⣇⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⡠⠤⢤⢤⠴⠃⠀⡀⠔⠊⠀⠠⢹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
34 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢺⠀⠀⠀⠣⡀⠀⠀⡤⠃⠠⣼⠃⢳⠈⠉⠉⣍⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠀⠀⠀⠀⠀⡜⢸⢀⡔⠉⠀⢀⡠⢔⠊⠉⠻⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
35 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡦⡀⠀⠀⠈⠑⠺⠤⣴⠟⠃⠀⠸⡆⠐⠀⢸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⠀⠀⢀⠃⢸⡃⣇⠀⡰⠟⠂⠁⠀⠀⠀⠙⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
36 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠀⠀⠀⠈⠺⠦⣄⣠⠤⠴⠊⠉⠀⠀⠀⡼⠁⠀⠐⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢘⠀⠀⠀⢸⠀⢸⣇⠞⠉⠀⠀⠀⠀⢀⡠⠐⠀⠈⢣⠀⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
37 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜⠈⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⢿⣁⠀⠈⢀⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡈⢀⠀⠀⠰⠀⢸⠹⡄⠀⠀⢀⡠⠒⠁⠀⠀⠀⡠⠀⢳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
38 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢜⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⠋⠀⠈⠉⠓⠦⠄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡯⠀⠀⠀⣆⣼⡆⢙⣤⡐⠁⠀⠀⠀⡠⠔⠉⠀⠀⠀⠹⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
39 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢂⡠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⢾⠁⠉⠢⢄⡀⠀⠀⠀⠀⠈⠉⠁⠐⠒⠒⠒⠒⠒⠚⠓⠀⠈⠉⠀⠀⢧⠀⠘⢷⣀⡠⠔⠉⠀⠀⠀⠀⢀⠠⠀⠱⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
40 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠚⡱⠁⠀⠀⠀⠀⠈⠁⠒⠠⠤⢀⣀⣀⢀⠀⡀⢀⢀⡀⠀⠀⣀⡠⠔⠒⠂⠙⣆⠀⠀⠙⣦⠀⠀⠀⢀⠄⠊⠁⠀⠀⡀⠘⣄⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
41 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⢡⠊⠀⠀⠀⠀⠀⠀⠀⣰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠰⡄⠀⠹⡄⠀⠀⠀⠳⡄⠐⠁⠀⠀⢀⠔⠉⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
42 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠋⡔⠁⠀⠀⠀⠀⠀⠀⠀⣰⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⣷⠀⠀⠀⠀⠀⠀⠀⠀⣷⠀⠀⠹⡄⠀⠀⠀⠈⢷⣀⡠⠚⠁⠀⠀⢀⠄⠢⡀⠣⣀⠀⠀⠀⢀⣀⣤⣤⣄⠀⠀⠀⠀⠀ |
43 | ⠀⠀⠀⠀⠀⠀⠀⢀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⢁⠎⠀⠀⠀⠀⠀⠀⠀⠀⢰⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⣹⡄⠀⠀⠀⠀⠀⠀⠀⡇⡆⠀⠀⢳⠀⠀⠀⠀⠈⠙⢵⠀⠀⢀⠕⢁⠖⡠⠁⠀⠉⡖⠚⠉⠩⢿⡟⣿⣭⣷⣄⠀⠀⠀ |
44 | ⠀⠀⠀⠀⠀⠀⠀⡘⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⢡⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⡆⡎⡘⠀⠀⠀⠀⠀⠀⠀⠀⠀⣜⢣⠀⠀⠀⠀⠀⠀⠀⢹⠸⡀⠀⠐⢇⠀⠀⠀⠀⠀⠀⠑⢶⡁⠀⢸⡔⠁⠀⢠⠃⢁⠀⠀⠀⠒⣿⡽⣶⢾⣿⣷⣄⠀ |
45 | ⠀⠀⠀⠀⠀⠀⢰⠇⠀⠸⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⢣⠇⡄⠀⠀⠀⠀⠀⠀⠀⠀⢸⢠⠇⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢸⠀⠀⠀⠀⠀⠀⠀⠸⠀⡇⠀⠀⠸⡆⠀⠀⠀⠀⠀⠀⠘⢿⣦⣾⠀⠀⠀⡇⠀⢸⠀⠀⠀⠀⢸⣿⣷⣿⡿⣿⣿⣧ |
46 | ⠀⠀⠀⠀⠀⠀⢎⠀⠀⠀⡷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⡌⡘⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⡇⠀⠀⠄⠀⠀⠀⠀⡇⢸⠀⠀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠹⣴⠀⠀⡜⠀⠀⢘⣲⣄⣀⣈⣸⠿⢿⣯⣿⣽⣞⣿ |
47 | ⠀⠀⠀⠀⠀⠀⠀⢣⠀⡴⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠏⡸⢠⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⡸⢰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡀⡇⠀⠀⠀⠀⠀⠀⠀⢸⠈⡇⠀⠀⠈⢇⠀⠀⠀⠀⠀⠀⠀⠀⠸⠓⣜⠂⠀⣴⣿⣿⣷⣾⣯⣿⣦⠈⠉⠛⠻⠞⠉ |
48 | ⠀⠀⠀⠀⠀⠀⠀⠀⠙⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣄⡇⢜⡀⠤⣀⠀⠀⠀⠀⠀⠀⠀⡇⢓⠨⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡀⣇⠀⠀⠀⠀⠀⠀⠀⠈⡆⢥⠀⠀⠀⠘⡆⠀⠀⠀⠀⠀⠀⠀⠨⠀⠀⠓⢦⢿⣿⣿⣾⣷⣿⣿⡿⠀⠀⠀⠀⠀⠀ |
49 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠦⣀⠈⠑⠀⠦⠤⠄⠀⠀⠀⠀⣇⣽⠀⠀⠄⠀⠀⠀⠀⠀⠀⠒⠈⢸⠂⡏⠀⠠⠀⠀⠀⠀⠐⠀⠇⢸⠄⣀⣀⠀⠘⡄⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
50 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠒⣶⠤⠤⠤⠤⠤⠶⠖⠛⠉⠲⠤⣄⣀⣀⣀⢀⣀⣀⣤⣤⣼⣿⣧⣈⠉⠐⠒⠂⠀⠀⠀⢸⡻⠦⠤⣤⠤⠖⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
51 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⡀⠀⢠⣀⣤⠴⠖⠛⠋⠉⠉⠉⣩⡥⠬⠥⣬⣉⣹⡏⠉⠉⠉⠉⠉⠉⠒⠒⠒⠚⠿⠥⢤⣀⡀⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
52 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠩⡗⠚⠉⣀⠠⠤⠒⠒⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠉⠉⠉⠉⠁⠉⠁⠀⠀⠀⠒⠤⢩⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
53 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
54 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
55 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⠐⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⠀⠀⠀⠀⠀⠀⠀⠀ |
56 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠉⡄⠀⠀⠀⠀⠀⠀⠀ |
57 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠛⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠠⡟⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠃⠀⠘⡄⠀⠀⠀⠀⠀⠀ |
58 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⢸⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀⢨⡇⠀⠀⠀⠀⠐⠀⠀⠀⠀⠀⠀⠀⢈⡰⢯⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⡇⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀ |
59 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠴⠋⠀⢀⣸⣄⠇⠈⠢⢄⠀⠀⠀⠀⠀⠀⠀⠀⠠⠁⢸⢧⠀⠀⠀⠀⠀⠀⡀⠀⠀⢀⠔⠁⠊⠁⠈⢣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⡄⠀⣠⠋⠀⠀⠀⠀⠀⠀ |
60 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⢠⡤⠖⠋⠁⠀⠀⠠⢀⡿⠉⠙⠢⠤⠀⣉⠒⠤⣀⠀⠀⠀⠀⠀⠀⡿⢸⡀⠀⠀⠀⠀⠀⡀⠠⢖⠍⠀⠀⠀⠀⠀⠀⠻⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣤⠃⠀⠀⠀⠀⠀⠀⠀ |
61 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠤⠓⠋⠀⠀⠀⡀⠤⠀⠂⣠⠞⠀⠀⠀⠀⠀⠀⠀⠉⠀⠀⠁⠀⠀⠀⠀⢠⠇⣈⣇⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀⢀⠠⠂⠀⡄⠹⡀⠀⠀⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
62 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠖⠋⠀⠀⠀⠀⠀⠈⢀⠀⠠⠐⡴⢡⠂⠁⠂⠤⣤⣀⠀⠀⠀⠈⠢⠀⠀⠀⠀⠀⡼⠀⣼⢹⡀⠀⠀⠀⠀⢀⡠⠤⠏⠁⠀⠀⠀⠀⠀⣰⠀⢷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
63 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠔⠋⠀⠀⠀⠀⠀⠀⡀⠁⠀⠂⠀⠄⡜⢀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠉⠂⠲⡄⠤⠀⢠⡼⠁⢀⡟⠀⣧⠐⠒⠒⠽⠋⠁⠀⠀⠀⠀⡠⠤⠎⠁⠁⠀⠸⡀⠀⠀⠀⡀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
64 | ⠀⠀⠀⠀⠀⠀⠀⠀⢠⠞⠁⠀⠀⠀⠀⠀⠀⠀⠄⠀⡀⠁⢀⠂⡸⠀⠀⠈⠒⢤⡀⠀⠀⠀⠀⠀⠀⠀⢠⠃⠀⢀⡾⠁⣾⣸⠁⠀⡟⡆⠀⠀⡠⠖⠒⠚⠉⠉⠀⠀⠀⠀⠀⠀⠀⢀⡇⠀⠀⠀⢀⠝⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
65 | ⠀⠀⠀⠀⠀⠀⠀⡴⠁⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠐⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠉⠓⠢⢤⣀⢠⣃⣀⢀⡞⢁⡼⠛⠃⠀⣱⠁⢻⠈⠁⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠀⡇⠀⠀⡠⠋⠈⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
66 | ⠀⠀⠀⠀⠀⢠⣎⣠⡶⠗⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠁⠠⠈⢰⡇⠉⠂⢄⡀⠀⠀⠀⠀⠀⠀⠀⢁⠂⠀⢀⡟⠠⠞⠀⠠⡄⣱⠃⠀⠈⣇⣀⣀⡤⠆⠂⠂⠂⠂⠒⠉⠁⠁⠀⠀⠀⡇⢀⠎⠀⠀⠀⠀⠀⠁⠀⢠⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
67 | ⠀⠀⠀⠀⠀⢚⣷⡾⠁⠀⠀⠀⠀⠀⠀⢀⠀⠀⠁⠠⠈⠀⠄⢸⣇⠀⠀⠀⠀⠁⠂⠠⢀⠀⠀⠀⠎⠀⢀⡞⠀⠠⠀⠂⣽⣻⠃⠀⠀⠀⠘⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⡠⠚⠀⣧⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
68 | ⠀⠀⠀⠀⣠⢾⣿⠇⠀⠀⠀⠀⠀⠀⢀⠀⠀⠈⠀⠄⠐⠀⠠⢸⠁⠑⠤⢀⣀⠀⠀⠀⠀⠀⠀⠉⠀⢀⡏⠀⠐⠀⣡⢾⡟⠁⠀⠀⠀⠀⠀⠻⡄⠀⠀⠀⠀⣀⡤⠔⠋⠉⠀⠀⠀⠀⡟⠀⠀⠀⠀⠀⠀⠀⠀⠘⡄⢠⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
69 | ⠀⠀⠀⣰⠃⣯⢾⠀⢀⣴⡟⠀⠀⠀⠀⡀⠈⠀⠄⠀⠂⠈⢀⢸⠀⠀⠀⠀⠀⠀⠁⠑⠢⣀⡀⠀⢠⠟⠀⣈⣤⠞⠁⠈⠀⠀⠀⠀⠀⠀⠀⠀⢳⠐⠒⠊⠉⠀⠀⠀⠀⠀⠀⠀⢀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
70 | ⠀⠀⣰⠃⠀⣷⣿⣴⣟⡿⠁⠀⠀⣀⣁⠀⠀⠐⠀⡈⠀⢁⠀⣼⠄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢳⣎⣠⠖⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⠀⠀⠀⠀⢀⣀⣀⡀⠤⠂⠁⢠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
71 | ⠀⢠⠃⠀⠀⠉⢁⣼⡿⢶⣞⡿⣿⣿⡏⠀⠈⡀⠐⠀⢈⠀⣼⢹⠦⠀⠁⠂⠤⣀⠀⠀⠀⠀⠀⡾⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠚⣏⠁⠉⠉⠀⠀⠀⠀⠀⠀⠀⣸⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
72 | ⠀⡞⠀⠀⠀⠀⠞⠛⠛⠉⢁⣿⡿⣿⠁⣀⡐⢂⠄⢈⡆⢠⠇⣼⠀⠀⠀⠀⠀⠀⠀⠉⠐⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⠀⣀⡤⠄⠊⠹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
73 | ⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣼⡟⠁⢃⣤⣿⣷⠋⠐⣿⠈⠁⠀⠀⠀⠀⠀⠀⠀⡸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡒⠋⠉⠉⠉⠁⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
74 | ⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡿⢋⣿⢁⣴⣾⣿⣿⣟⣠⠟⡏⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⠀⠀⠀⠀⠀⠀⢀⡀⠠⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
75 | ⡏⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠘⣯⣼⣿⠟⣿⣿⠟⠁⣸⠁⠒⠠⢀⡀⠀⠠⠈⢀⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣸⡧⠖⠒⠒⠁⠉⠁⠀⠀⢻⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
76 | ⣧⠀⣴⡇⠀⢰⠀⠀⠀⢀⠀⡜⠀⠀⠹⡏⢁⣴⠛⠁⠀⢠⠇⠀⠀⠀⠀⠀⠜⠁⠀⡜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⣧⢹⣒⣒⠶⠶⢦⡤⠝⠛⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
77 | ⢹⠞⢠⡁⠀⢷⠀⠀⢀⠎⠸⠀⠀⠀⢀⣴⠋⠁⠀⠀⢀⠏⠈⠉⠀⠀⢀⣀⠀⠤⠐⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
78 | ⠀⠈⠸⡇⠀⠈⠆⢀⠇⠀⠁⠀⣼⢠⡞⡁⠀⠀⠀⢀⠏⠀⠀⠀⠚⠛⠂⠀⠀⠀⢀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⣀⠀⠀⢀⣀⣀⣀⣀⠠⠄⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
79 | ⠀⠀⠀⠹⡄⠀⠈⠚⠂⠀⠀⣴⣿⡎⠀⠀⠀⠀⠀⡞⠀⠀⠐⠒⠐⠀⠀⠀⠀⠈⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠧⠀⠀⠀⠀⠀⠀⠀⠀⠀⡂⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
80 | ⠀⠀⠀⠀⠙⢄⠀⠀⠀⠀⠀⡇⠈⠀⠀⠀⠀⠀⠈⢳⠀⠀⠀⠀⢀⠀⠀⠤⠄⠒⠂⠨⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
81 | ⠀⠀⠀⠀⠀⠀⠙⠢⢤⣀⡀⢳⢀⣀⣠⠤⠤⠤⠤⠬⡇⠒⠈⠉⠀⠀⠀⠀⠀⠀⢀⠀⠘⣆⢀⣀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
82 | ⠀⠀⠀⠀⠀⠀⠀⣠⠤⠂⠈⠙⠁⡀⠄⢂⠐⡀⠆⠐⣻⠀⠀⢀⡀⠄⠐⠂⠉⢀⣀⣀⣠⣼⣦⣤⣂⠐⠐⡈⠐⢂⠁⠒⠠⢁⠂⠌⢉⠑⢦⠀⣠⠤⠴⠾⢲⠶⠶⠤⠤⢤⣀⣀⠒⠀⠤⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
83 | ⠀⠀⠀⠀⠀⠀⠀⠳⠤⣌⣌⣠⠁⡐⠈⠄⢂⠐⡈⠄⣹⡖⠀⣀⣠⣦⣶⣿⣿⣭⣽⣶⣷⣽⣶⣬⣭⡳⣥⠀⠡⠀⠌⠠⢁⠂⠌⡀⠂⠌⢀⣾⣥⣶⣶⣿⣿⢿⡿⣿⣿⣿⣿⣮⣽⣿⣶⣄⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
84 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡤⠌⠐⡀⢂⠐⠠⢈⣷⣿⣿⣿⣟⡿⣽⣻⣿⣟⡷⣯⣟⣿⣿⣟⣿⣿⠇⠠⢁⠈⡐⠠⠈⠄⠠⢁⠂⣼⣿⣯⣷⣻⣿⣽⢯⣟⣷⣿⣟⣾⣽⣻⣟⡿⣿⡧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
85 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠦⣌⡐⢀⠂⡈⠐⡀⠻⣿⣿⣿⣾⣿⣿⣽⣯⣿⣟⣷⣿⣾⣿⣿⣿⡿⠀⡁⠂⡐⠠⠁⠌⠠⠁⠂⠄⡈⢿⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣾⣷⣿⣾⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
86 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠑⠒⠃⠐⠤⠀⠙⠛⠿⠿⣿⣿⣿⣿⠿⠿⠟⠛⢋⠉⡀⠄⢂⠐⠠⠐⠠⠁⠌⠠⠁⠌⠠⠐⡀⠈⠉⠛⠛⠟⠻⠟⠟⠻⠛⠛⠛⠛⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
87 | ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠀⠒⠐⠒⠂⠂⠂⠑⠀⠃⠈⠀⠃⠈⠀⠁⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |
88 | |
89 | ]]-- |
90 | |
91 | local plr = game:GetService("Players").LocalPlayer |
92 | |
93 | function RunCustomAnimation(Char) |
94 | if Char:WaitForChild("Animate") ~= nil then |
95 | Char.Animate.Disabled = true |
96 | end |
97 | |
98 | Char:WaitForChild("Humanoid") |
99 | |
100 | for i,v in next, Char.Humanoid:GetPlayingAnimationTracks() do |
101 | v:Stop() |
102 | end |
103 | |
104 | --fake script |
105 | local script = Char.Animate |
106 | |
107 | local Character = Char |
108 | local Humanoid = Character:WaitForChild("Humanoid") |
109 | local pose = "Standing" |
110 | |
111 | local UserGameSettings = UserSettings():GetService("UserGameSettings") |
112 | |
113 | local userNoUpdateOnLoopSuccess, userNoUpdateOnLoopValue = pcall(function() return UserSettings():IsUserFeatureEnabled("UserNoUpdateOnLoop") end) |
114 | local userNoUpdateOnLoop = userNoUpdateOnLoopSuccess and userNoUpdateOnLoopValue |
115 | |
116 | local AnimationSpeedDampeningObject = script:FindFirstChild("ScaleDampeningPercent") |
117 | local HumanoidHipHeight = 2 |
118 | |
119 | local humanoidSpeed = 0 -- speed most recently sent to us from onRunning() |
120 | local cachedRunningSpeed = 0 -- The most recent speed used to compute blends. Tiny variations from cachedRunningSpeed will not cause animation updates. |
121 | local cachedLocalDirection = {x=0.0, y=0.0} -- unit 2D object space direction of motion |
122 | local smallButNotZero = 0.0001 -- We want weights to be small but not so small the animation stops |
123 | local runBlendtime = 0.2 |
124 | local lastLookVector = Vector3.new(0.0, 0.0, 0.0) -- used to track whether rootPart orientation is changing. |
125 | local lastBlendTime = 0 -- The last time we blended velocities |
126 | local WALK_SPEED = 6.4 |
127 | local RUN_SPEED = 12.8 |
128 | |
129 | local EMOTE_TRANSITION_TIME = 0.1 |
130 | |
131 | local currentAnim = "" |
132 | local currentAnimInstance = nil |
133 | local currentAnimTrack = nil |
134 | local currentAnimKeyframeHandler = nil |
135 | local currentAnimSpeed = 1.0 |
136 | |
137 | local PreloadedAnims = {} |
138 | |
139 | local animTable = {} |
140 | local animNames = { |
141 | idle = { |
142 | { id = "http://www.roblox.com/asset/?id=12521158637", weight = 9 }, |
143 | { id = "http://www.roblox.com/asset/?id=12521162526", weight = 1 }, |
144 | }, |
145 | walk = { |
146 | { id = "http://www.roblox.com/asset/?id=12518152696", weight = 10 } |
147 | }, |
148 | run = { |
149 | { id = "http://www.roblox.com/asset/?id=12518152696", weight = 10 } |
150 | }, |
151 | jump = { |
152 | { id = "http://www.roblox.com/asset/?id=12520880485", weight = 10 } |
153 | }, |
154 | fall = { |
155 | { id = "http://www.roblox.com/asset/?id=12520972571", weight = 10 } |
156 | }, |
157 | climb = { |
158 | { id = "http://www.roblox.com/asset/?id=12520982150", weight = 10 } |
159 | }, |
160 | sit = { |
161 | { id = "http://www.roblox.com/asset/?id=12520993168", weight = 10 } |
162 | }, |
163 | toolnone = { |
164 | { id = "http://www.roblox.com/asset/?id=12520996634", weight = 10 } |
165 | }, |
166 | toolslash = { |
167 | { id = "http://www.roblox.com/asset/?id=12520999032", weight = 10 } |
168 | }, |
169 | toollunge = { |
170 | { id = "http://www.roblox.com/asset/?id=12521002003", weight = 10 } |
171 | }, |
172 | wave = { |
173 | { id = "http://www.roblox.com/asset/?id=12521004586", weight = 10 } |
174 | }, |
175 | point = { |
176 | { id = "http://www.roblox.com/asset/?id=12521007694", weight = 10 } |
177 | }, |
178 | dance = { |
179 | { id = "http://www.roblox.com/asset/?id=12521009666", weight = 10 }, |
180 | { id = "http://www.roblox.com/asset/?id=12521151637", weight = 10 }, |
181 | { id = "http://www.roblox.com/asset/?id=12521015053", weight = 10 } |
182 | }, |
183 | dance2 = { |
184 | { id = "http://www.roblox.com/asset/?id=12521169800", weight = 10 }, |
185 | { id = "http://www.roblox.com/asset/?id=12521173533", weight = 10 }, |
186 | { id = "http://www.roblox.com/asset/?id=12521027874", weight = 10 } |
187 | }, |
188 | dance3 = { |
189 | { id = "http://www.roblox.com/asset/?id=12521178362", weight = 10 }, |
190 | { id = "http://www.roblox.com/asset/?id=12521181508", weight = 10 }, |
191 | { id = "http://www.roblox.com/asset/?id=12521184133", weight = 10 } |
192 | }, |
193 | laugh = { |
194 | { id = "http://www.roblox.com/asset/?id=12521018724", weight = 10 } |
195 | }, |
196 | cheer = { |
197 | { id = "http://www.roblox.com/asset/?id=12521021991", weight = 10 } |
198 | }, |
199 | } |
200 | |
201 | |
202 | local strafingLocomotionMap = {} |
203 | local fallbackLocomotionMap = {} |
204 | local locomotionMap = strafingLocomotionMap |
205 | -- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote |
206 | local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh = false, cheer = false} |
207 | |
208 | math.randomseed(tick()) |
209 | |
210 | function findExistingAnimationInSet(set, anim) |
211 | if set == nil or anim == nil then |
212 | return 0 |
213 | end |
214 | |
215 | for idx = 1, set.count, 1 do |
216 | if set[idx].anim.AnimationId == anim.AnimationId then |
217 | return idx |
218 | end |
219 | end |
220 | |
221 | return 0 |
222 | end |
223 | |
224 | function configureAnimationSet(name, fileList) |
225 | if (animTable[name] ~= nil) then |
226 | for _, connection in pairs(animTable[name].connections) do |
227 | connection:disconnect() |
228 | end |
229 | end |
230 | animTable[name] = {} |
231 | animTable[name].count = 0 |
232 | animTable[name].totalWeight = 0 |
233 | animTable[name].connections = {} |
234 | |
235 | -- uncomment this section to allow players to load with their |
236 | -- own (non-classic) animations |
237 | --[[ |
238 | local config = script:FindFirstChild(name) |
239 | if (config ~= nil) then |
240 | table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end)) |
241 | table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end)) |
242 | |
243 | local idx = 0 |
244 | |
245 | for _, childPart in pairs(config:GetChildren()) do |
246 | if (childPart:IsA("Animation")) then |
247 | local newWeight = 1 |
248 | local weightObject = childPart:FindFirstChild("Weight") |
249 | if (weightObject ~= nil) then |
250 | newWeight = weightObject.Value |
251 | end |
252 | animTable[name].count = animTable[name].count + 1 |
253 | idx = animTable[name].count |
254 | animTable[name][idx] = {} |
255 | animTable[name][idx].anim = childPart |
256 | animTable[name][idx].weight = newWeight |
257 | animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight |
258 | table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end)) |
259 | table.insert(animTable[name].connections, childPart.ChildAdded:connect(function(property) configureAnimationSet(name, fileList) end)) |
260 | table.insert(animTable[name].connections, childPart.ChildRemoved:connect(function(property) configureAnimationSet(name, fileList) end)) |
261 | local lv = childPart:GetAttribute("LinearVelocity") |
262 | if lv then |
263 | strafingLocomotionMap[name] = {lv=lv, speed = lv.Magnitude} |
264 | end |
265 | if name == "run" or name == "walk" then |
266 | |
267 | if lv then |
268 | fallbackLocomotionMap[name] = strafingLocomotionMap[name] |
269 | else |
270 | local speed = name == "run" and RUN_SPEED or WALK_SPEED |
271 | fallbackLocomotionMap[name] = {lv=Vector2.new(0.0, speed), speed = speed} |
272 | locomotionMap = fallbackLocomotionMap |
273 | -- If you don't have a linear velocity with your run or walk, you can't blend/strafe |
274 | --warn("Strafe blending disabled. No linear velocity information for "..'"'.."walk"..'"'.." and "..'"'.."run"..'"'..".") |
275 | end |
276 | |
277 | end |
278 | end |
279 | end |
280 | end |
281 | ]] |
282 | |
283 | -- if you uncomment the above section, comment out this "if"-block |
284 | if name == "run" or name == "walk" then |
285 | local speed = name == "run" and RUN_SPEED or WALK_SPEED |
286 | fallbackLocomotionMap[name] = {lv=Vector2.new(0.0, speed), speed = speed} |
287 | locomotionMap = fallbackLocomotionMap |
288 | -- If you don't have a linear velocity with your run or walk, you can't blend/strafe |
289 | --warn("Strafe blending disabled. No linear velocity information for "..'"'.."walk"..'"'.." and "..'"'.."run"..'"'..".") |
290 | end |
291 | |
292 | |
293 | -- fallback to defaults |
294 | if (animTable[name].count <= 0) then |
295 | for idx, anim in pairs(fileList) do |
296 | animTable[name][idx] = {} |
297 | animTable[name][idx].anim = Instance.new("Animation") |
298 | animTable[name][idx].anim.Name = name |
299 | animTable[name][idx].anim.AnimationId = anim.id |
300 | animTable[name][idx].weight = anim.weight |
301 | animTable[name].count = animTable[name].count + 1 |
302 | animTable[name].totalWeight = animTable[name].totalWeight + anim.weight |
303 | end |
304 | end |
305 | |
306 | -- preload anims |
307 | for i, animType in pairs(animTable) do |
308 | for idx = 1, animType.count, 1 do |
309 | if PreloadedAnims[animType[idx].anim.AnimationId] == nil then |
310 | Humanoid:LoadAnimation(animType[idx].anim) |
311 | PreloadedAnims[animType[idx].anim.AnimationId] = true |
312 | end |
313 | end |
314 | end |
315 | end |
316 | |
317 | -- Setup animation objects |
318 | function scriptChildModified(child) |
319 | local fileList = animNames[child.Name] |
320 | if (fileList ~= nil) then |
321 | configureAnimationSet(child.Name, fileList) |
322 | else |
323 | if child:isA("StringValue") then |
324 | animNames[child.Name] = {} |
325 | configureAnimationSet(child.Name, animNames[child.Name]) |
326 | end |
327 | end |
328 | end |
329 | |
330 | script.ChildAdded:connect(scriptChildModified) |
331 | script.ChildRemoved:connect(scriptChildModified) |
332 | |
333 | -- Clear any existing animation tracks |
334 | -- Fixes issue with characters that are moved in and out of the Workspace accumulating tracks |
335 | local animator = if Humanoid then Humanoid:FindFirstChildOfClass("Animator") else nil |
336 | if animator then |
337 | local animTracks = animator:GetPlayingAnimationTracks() |
338 | for i,track in ipairs(animTracks) do |
339 | track:Stop(0) |
340 | track:Destroy() |
341 | end |
342 | end |
343 | |
344 | for name, fileList in pairs(animNames) do |
345 | configureAnimationSet(name, fileList) |
346 | end |
347 | for _,child in script:GetChildren() do |
348 | if child:isA("StringValue") and not animNames[child.name] then |
349 | animNames[child.Name] = {} |
350 | configureAnimationSet(child.Name, animNames[child.Name]) |
351 | end |
352 | end |
353 | |
354 | -- ANIMATION |
355 | |
356 | -- declarations |
357 | local toolAnim = "None" |
358 | local toolAnimTime = 0 |
359 | |
360 | local jumpAnimTime = 0 |
361 | local jumpAnimDuration = 0.31 |
362 | |
363 | local toolTransitionTime = 0.1 |
364 | local fallTransitionTime = 0.2 |
365 | |
366 | local currentlyPlayingEmote = false |
367 | |
368 | -- functions |
369 | |
370 | function stopAllAnimations() |
371 | local oldAnim = currentAnim |
372 | |
373 | -- return to idle if finishing an emote |
374 | if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then |
375 | oldAnim = "idle" |
376 | end |
377 | |
378 | if currentlyPlayingEmote then |
379 | oldAnim = "idle" |
380 | currentlyPlayingEmote = false |
381 | end |
382 | |
383 | currentAnim = "" |
384 | currentAnimInstance = nil |
385 | if (currentAnimKeyframeHandler ~= nil) then |
386 | currentAnimKeyframeHandler:disconnect() |
387 | end |
388 | |
389 | if (currentAnimTrack ~= nil) then |
390 | currentAnimTrack:Stop() |
391 | currentAnimTrack:Destroy() |
392 | currentAnimTrack = nil |
393 | end |
394 | |
395 | for _,v in pairs(locomotionMap) do |
396 | if v.track then |
397 | v.track:Stop() |
398 | v.track:Destroy() |
399 | v.track = nil |
400 | end |
401 | end |
402 | |
403 | return oldAnim |
404 | end |
405 | |
406 | function getHeightScale() |
407 | if Humanoid then |
408 | if not Humanoid.AutomaticScalingEnabled then |
409 | return 1 |
410 | end |
411 | |
412 | local scale = Humanoid.HipHeight / HumanoidHipHeight |
413 | if AnimationSpeedDampeningObject == nil then |
414 | AnimationSpeedDampeningObject = script:FindFirstChild("ScaleDampeningPercent") |
415 | end |
416 | if AnimationSpeedDampeningObject ~= nil then |
417 | scale = 1 + (Humanoid.HipHeight - HumanoidHipHeight) * AnimationSpeedDampeningObject.Value / HumanoidHipHeight |
418 | end |
419 | return scale |
420 | end |
421 | return 1 |
422 | end |
423 | |
424 | |
425 | local function signedAngle(a, b) |
426 | return -math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y) |
427 | end |
428 | |
429 | local angleWeight = 2.0 |
430 | local function get2DWeight(px, p1, p2, sx, s1, s2) |
431 | local avgLength = 0.5 * (s1 + s2) |
432 | |
433 | local p_1 = {x = (sx - s1)/avgLength, y = (angleWeight * signedAngle(p1, px))} |
434 | local p12 = {x = (s2 - s1)/avgLength, y = (angleWeight * signedAngle(p1, p2))} |
435 | local denom = smallButNotZero + (p12.x*p12.x + p12.y*p12.y) |
436 | local numer = p_1.x * p12.x + p_1.y * p12.y |
437 | local r = math.clamp(1.0 - numer/denom, 0.0, 1.0) |
438 | return r |
439 | end |
440 | |
441 | local function blend2D(targetVelo, targetSpeed) |
442 | local h = {} |
443 | local sum = 0.0 |
444 | for n,v1 in pairs(locomotionMap) do |
445 | if targetVelo.x * v1.lv.x < 0.0 or targetVelo.y * v1.lv.y < 0 then |
446 | -- Require same quadrant as target |
447 | h[n] = 0.0 |
448 | continue |
449 | end |
450 | h[n] = math.huge |
451 | for j,v2 in pairs(locomotionMap) do |
452 | if targetVelo.x * v2.lv.x < 0.0 or targetVelo.y * v2.lv.y < 0 then |
453 | -- Require same quadrant as target |
454 | continue |
455 | end |
456 | h[n] = math.min(h[n], get2DWeight(targetVelo, v1.lv, v2.lv, targetSpeed, v1.speed, v2.speed)) |
457 | end |
458 | sum += h[n] |
459 | end |
460 | |
461 | --truncates below 10% contribution |
462 | local sum2 = 0.0 |
463 | local weightedVeloX = 0 |
464 | local weightedVeloY = 0 |
465 | for n,v in pairs(locomotionMap) do |
466 | |
467 | if (h[n] / sum > 0.1) then |
468 | sum2 += h[n] |
469 | weightedVeloX += h[n] * v.lv.x |
470 | weightedVeloY += h[n] * v.lv.y |
471 | else |
472 | h[n] = 0.0 |
473 | end |
474 | end |
475 | local animSpeed |
476 | local weightedSpeedSquared = weightedVeloX * weightedVeloX + weightedVeloY * weightedVeloY |
477 | if weightedSpeedSquared > smallButNotZero then |
478 | animSpeed = math.sqrt(targetSpeed * targetSpeed / weightedSpeedSquared) |
479 | else |
480 | animSpeed = 0 |
481 | end |
482 | |
483 | animSpeed = animSpeed / getHeightScale() |
484 | local groupTimePosition = 0 |
485 | for n,v in pairs(locomotionMap) do |
486 | if v.track.IsPlaying then |
487 | groupTimePosition = v.track.TimePosition |
488 | break |
489 | end |
490 | end |
491 | for n,v in pairs(locomotionMap) do |
492 | -- if not loco |
493 | if h[n] > 0.0 then |
494 | if not v.track.IsPlaying then |
495 | v.track:Play(runBlendtime) |
496 | v.track.TimePosition = groupTimePosition |
497 | end |
498 | |
499 | local weight = math.max(smallButNotZero, h[n] / sum2) |
500 | v.track:AdjustWeight(weight, runBlendtime) |
501 | v.track:AdjustSpeed(animSpeed) |
502 | else |
503 | v.track:Stop(runBlendtime) |
504 | end |
505 | end |
506 | |
507 | end |
508 | |
509 | local function getWalkDirection() |
510 | local walkToPoint = Humanoid.WalkToPoint |
511 | local walkToPart = Humanoid.WalkToPart |
512 | if Humanoid.MoveDirection ~= Vector3.zero then |
513 | return Humanoid.MoveDirection |
514 | elseif walkToPart or walkToPoint ~= Vector3.zero then |
515 | local destination |
516 | if walkToPart then |
517 | destination = walkToPart.CFrame:PointToWorldSpace(walkToPoint) |
518 | else |
519 | destination = walkToPoint |
520 | end |
521 | local moveVector = Vector3.zero |
522 | if Humanoid.RootPart then |
523 | moveVector = destination - Humanoid.RootPart.CFrame.Position |
524 | moveVector = Vector3.new(moveVector.x, 0.0, moveVector.z) |
525 | local mag = moveVector.Magnitude |
526 | if mag > 0.01 then |
527 | moveVector /= mag |
528 | end |
529 | end |
530 | return moveVector |
531 | else |
532 | return Humanoid.MoveDirection |
533 | end |
534 | end |
535 | |
536 | local function updateVelocity(currentTime) |
537 | |
538 | local tempDir |
539 | |
540 | if locomotionMap == strafingLocomotionMap then |
541 | |
542 | local moveDirection = getWalkDirection() |
543 | |
544 | if not Humanoid.RootPart then |
545 | return |
546 | end |
547 | |
548 | local cframe = Humanoid.RootPart.CFrame |
549 | if math.abs(cframe.UpVector.Y) < smallButNotZero or pose ~= "Running" or humanoidSpeed < 0.001 then |
550 | -- We are horizontal! Do something (turn off locomotion) |
551 | for n,v in pairs(locomotionMap) do |
552 | if v.track then |
553 | v.track:AdjustWeight(smallButNotZero, runBlendtime) |
554 | end |
555 | end |
556 | return |
557 | end |
558 | local lookat = cframe.LookVector |
559 | local direction = Vector3.new(lookat.X, 0.0, lookat.Z) |
560 | direction = direction / direction.Magnitude --sensible upVector means this is non-zero. |
561 | local ly = moveDirection:Dot(direction) |
562 | if ly <= 0.0 and ly > -0.05 then |
563 | ly = smallButNotZero -- break quadrant ties in favor of forward-friendly strafes |
564 | end |
565 | local lx = direction.X*moveDirection.Z - direction.Z*moveDirection.X |
566 | local tempDir = Vector2.new(lx, ly) -- root space moveDirection |
567 | local delta = Vector2.new(tempDir.x-cachedLocalDirection.x, tempDir.y-cachedLocalDirection.y) |
568 | -- Time check serves the purpose of the old keyframeReached sync check, as it syncs anim timePosition |
569 | if delta:Dot(delta) > 0.001 or math.abs(humanoidSpeed - cachedRunningSpeed) > 0.01 or currentTime - lastBlendTime > 1 then |
570 | cachedLocalDirection = tempDir |
571 | cachedRunningSpeed = humanoidSpeed |
572 | lastBlendTime = currentTime |
573 | blend2D(cachedLocalDirection, cachedRunningSpeed) |
574 | end |
575 | else |
576 | if math.abs(humanoidSpeed - cachedRunningSpeed) > 0.01 or currentTime - lastBlendTime > 1 then |
577 | cachedRunningSpeed = humanoidSpeed |
578 | lastBlendTime = currentTime |
579 | blend2D(Vector2.yAxis, cachedRunningSpeed) |
580 | end |
581 | end |
582 | end |
583 | |
584 | function setAnimationSpeed(speed) |
585 | if currentAnim ~= "walk" then |
586 | if speed ~= currentAnimSpeed then |
587 | currentAnimSpeed = speed |
588 | currentAnimTrack:AdjustSpeed(currentAnimSpeed) |
589 | end |
590 | end |
591 | end |
592 | |
593 | function keyFrameReachedFunc(frameName) |
594 | if (frameName == "End") then |
595 | local repeatAnim = currentAnim |
596 | -- return to idle if finishing an emote |
597 | if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then |
598 | repeatAnim = "idle" |
599 | end |
600 | |
601 | if currentlyPlayingEmote then |
602 | if currentAnimTrack.Looped then |
603 | -- Allow the emote to loop |
604 | return |
605 | end |
606 | |
607 | repeatAnim = "idle" |
608 | currentlyPlayingEmote = false |
609 | end |
610 | |
611 | local animSpeed = currentAnimSpeed |
612 | playAnimation(repeatAnim, 0.15, Humanoid) |
613 | setAnimationSpeed(animSpeed) |
614 | end |
615 | end |
616 | |
617 | function rollAnimation(animName) |
618 | local roll = math.random(1, animTable[animName].totalWeight) |
619 | local origRoll = roll |
620 | local idx = 1 |
621 | while (roll > animTable[animName][idx].weight) do |
622 | roll = roll - animTable[animName][idx].weight |
623 | idx = idx + 1 |
624 | end |
625 | return idx |
626 | end |
627 | |
628 | local maxVeloX, minVeloX, maxVeloY, minVeloY |
629 | |
630 | local function destroyRunAnimations() |
631 | for _,v in pairs(strafingLocomotionMap) do |
632 | if v.track then |
633 | v.track:Stop() |
634 | v.track:Destroy() |
635 | v.track = nil |
636 | end |
637 | end |
638 | for _,v in pairs(fallbackLocomotionMap) do |
639 | if v.track then |
640 | v.track:Stop() |
641 | v.track:Destroy() |
642 | v.track = nil |
643 | end |
644 | end |
645 | cachedRunningSpeed = 0 |
646 | end |
647 | |
648 | local function resetVelocityBounds(velo) |
649 | minVeloX = 0 |
650 | maxVeloX = 0 |
651 | minVeloY = 0 |
652 | maxVeloY = 0 |
653 | end |
654 | |
655 | local function updateVelocityBounds(velo) |
656 | if velo then |
657 | if velo.x > maxVeloX then maxVeloX = velo.x end |
658 | if velo.y > maxVeloY then maxVeloY = velo.y end |
659 | if velo.x < minVeloX then minVeloX = velo.x end |
660 | if velo.y < minVeloY then minVeloY = velo.y end |
661 | end |
662 | end |
663 | |
664 | local function checkVelocityBounds(velo) |
665 | if maxVeloX == 0 or minVeloX == 0 or maxVeloY == 0 or minVeloY == 0 then |
666 | if locomotionMap == strafingLocomotionMap then |
667 | warn("Strafe blending disabled. Not all quadrants of motion represented.") |
668 | end |
669 | locomotionMap = fallbackLocomotionMap |
670 | else |
671 | locomotionMap = strafingLocomotionMap |
672 | end |
673 | end |
674 | |
675 | local function setupWalkAnimation(anim, animName, transitionTime, humanoid) |
676 | resetVelocityBounds() |
677 | -- check to see if we need to blend a walk/run animation |
678 | for n,v in pairs(locomotionMap) do |
679 | v.track = humanoid:LoadAnimation(animTable[n][1].anim) |
680 | v.track.Priority = Enum.AnimationPriority.Core |
681 | updateVelocityBounds(v.lv) |
682 | end |
683 | checkVelocityBounds() |
684 | end |
685 | |
686 | local function switchToAnim(anim, animName, transitionTime, humanoid) |
687 | -- switch animation |
688 | if (anim ~= currentAnimInstance) then |
689 | |
690 | if (currentAnimTrack ~= nil) then |
691 | currentAnimTrack:Stop(transitionTime) |
692 | currentAnimTrack:Destroy() |
693 | end |
694 | if (currentAnimKeyframeHandler ~= nil) then |
695 | currentAnimKeyframeHandler:disconnect() |
696 | end |
697 | |
698 | |
699 | currentAnimSpeed = 1.0 |
700 | |
701 | currentAnim = animName |
702 | currentAnimInstance = anim -- nil in the case of locomotion |
703 | |
704 | if animName == "walk" then |
705 | setupWalkAnimation(anim, animName, transitionTime, humanoid) |
706 | else |
707 | destroyRunAnimations() |
708 | -- load it to the humanoid; get AnimationTrack |
709 | currentAnimTrack = humanoid:LoadAnimation(anim) |
710 | currentAnimTrack.Priority = Enum.AnimationPriority.Core |
711 | |
712 | currentAnimTrack:Play(transitionTime) |
713 | |
714 | -- set up keyframe name triggers |
715 | currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc) |
716 | end |
717 | end |
718 | end |
719 | |
720 | function playAnimation(animName, transitionTime, humanoid) |
721 | local idx = rollAnimation(animName) |
722 | local anim = animTable[animName][idx].anim |
723 | |
724 | switchToAnim(anim, animName, transitionTime, humanoid) |
725 | currentlyPlayingEmote = false |
726 | end |
727 | |
728 | function playEmote(emoteAnim, transitionTime, humanoid) |
729 | switchToAnim(emoteAnim, emoteAnim.Name, transitionTime, humanoid) |
730 | currentlyPlayingEmote = true |
731 | end |
732 | |
733 | ------------------------------------------------------------------------------------------- |
734 | ------------------------------------------------------------------------------------------- |
735 | |
736 | local toolAnimName = "" |
737 | local toolAnimTrack = nil |
738 | local toolAnimInstance = nil |
739 | local currentToolAnimKeyframeHandler = nil |
740 | |
741 | function toolKeyFrameReachedFunc(frameName) |
742 | if (frameName == "End") then |
743 | playToolAnimation(toolAnimName, 0.0, Humanoid) |
744 | end |
745 | end |
746 | |
747 | |
748 | function playToolAnimation(animName, transitionTime, humanoid, priority) |
749 | local idx = rollAnimation(animName) |
750 | local anim = animTable[animName][idx].anim |
751 | |
752 | if (toolAnimInstance ~= anim) then |
753 | |
754 | if (toolAnimTrack ~= nil) then |
755 | toolAnimTrack:Stop() |
756 | toolAnimTrack:Destroy() |
757 | transitionTime = 0 |
758 | end |
759 | |
760 | -- load it to the humanoid; get AnimationTrack |
761 | toolAnimTrack = humanoid:LoadAnimation(anim) |
762 | if priority then |
763 | toolAnimTrack.Priority = priority |
764 | end |
765 | |
766 | -- play the animation |
767 | toolAnimTrack:Play(transitionTime) |
768 | toolAnimName = animName |
769 | toolAnimInstance = anim |
770 | |
771 | currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc) |
772 | end |
773 | end |
774 | |
775 | function stopToolAnimations() |
776 | local oldAnim = toolAnimName |
777 | |
778 | if (currentToolAnimKeyframeHandler ~= nil) then |
779 | currentToolAnimKeyframeHandler:disconnect() |
780 | end |
781 | |
782 | toolAnimName = "" |
783 | toolAnimInstance = nil |
784 | if (toolAnimTrack ~= nil) then |
785 | toolAnimTrack:Stop() |
786 | toolAnimTrack:Destroy() |
787 | toolAnimTrack = nil |
788 | end |
789 | |
790 | return oldAnim |
791 | end |
792 | |
793 | ------------------------------------------------------------------------------------------- |
794 | ------------------------------------------------------------------------------------------- |
795 | -- STATE CHANGE HANDLERS |
796 | |
797 | function onRunning(speed) |
798 | local movedDuringEmote = currentlyPlayingEmote and Humanoid.MoveDirection == Vector3.new(0, 0, 0) |
799 | local speedThreshold = movedDuringEmote and Humanoid.WalkSpeed or 0.75 |
800 | humanoidSpeed = speed |
801 | if speed > speedThreshold then |
802 | playAnimation("walk", 0.2, Humanoid) |
803 | if pose ~= "Running" then |
804 | pose = "Running" |
805 | updateVelocity(0) -- Force velocity update in response to state change |
806 | end |
807 | else |
808 | if emoteNames[currentAnim] == nil and not currentlyPlayingEmote then |
809 | playAnimation("idle", 0.2, Humanoid) |
810 | pose = "Standing" |
811 | end |
812 | end |
813 | |
814 | |
815 | |
816 | end |
817 | |
818 | function onDied() |
819 | pose = "Dead" |
820 | end |
821 | |
822 | function onJumping() |
823 | playAnimation("jump", 0.1, Humanoid) |
824 | jumpAnimTime = jumpAnimDuration |
825 | pose = "Jumping" |
826 | end |
827 | |
828 | function onClimbing(speed) |
829 | local scale = 5.0 |
830 | playAnimation("climb", 0.1, Humanoid) |
831 | setAnimationSpeed(speed / scale) |
832 | pose = "Climbing" |
833 | end |
834 | |
835 | function onGettingUp() |
836 | pose = "GettingUp" |
837 | end |
838 | |
839 | function onFreeFall() |
840 | if (jumpAnimTime <= 0) then |
841 | playAnimation("fall", fallTransitionTime, Humanoid) |
842 | end |
843 | pose = "FreeFall" |
844 | end |
845 | |
846 | function onFallingDown() |
847 | pose = "FallingDown" |
848 | end |
849 | |
850 | function onSeated() |
851 | pose = "Seated" |
852 | end |
853 | |
854 | function onPlatformStanding() |
855 | pose = "PlatformStanding" |
856 | end |
857 | |
858 | ------------------------------------------------------------------------------------------- |
859 | ------------------------------------------------------------------------------------------- |
860 | |
861 | function onSwimming(speed) |
862 | if speed > 0 then |
863 | pose = "Running" |
864 | else |
865 | pose = "Standing" |
866 | end |
867 | end |
868 | |
869 | function animateTool() |
870 | if (toolAnim == "None") then |
871 | playToolAnimation("toolnone", toolTransitionTime, Humanoid, Enum.AnimationPriority.Idle) |
872 | return |
873 | end |
874 | |
875 | if (toolAnim == "Slash") then |
876 | playToolAnimation("toolslash", 0, Humanoid, Enum.AnimationPriority.Action) |
877 | return |
878 | end |
879 | |
880 | if (toolAnim == "Lunge") then |
881 | playToolAnimation("toollunge", 0, Humanoid, Enum.AnimationPriority.Action) |
882 | return |
883 | end |
884 | end |
885 | |
886 | function getToolAnim(tool) |
887 | for _, c in ipairs(tool:GetChildren()) do |
888 | if c.Name == "toolanim" and c.className == "StringValue" then |
889 | return c |
890 | end |
891 | end |
892 | return nil |
893 | end |
894 | |
895 | local lastTick = 0 |
896 | |
897 | function stepAnimate(currentTime) |
898 | local amplitude = 1 |
899 | local frequency = 1 |
900 | local deltaTime = currentTime - lastTick |
901 | lastTick = currentTime |
902 | |
903 | local climbFudge = 0 |
904 | local setAngles = false |
905 | |
906 | if (jumpAnimTime > 0) then |
907 | jumpAnimTime = jumpAnimTime - deltaTime |
908 | end |
909 | |
910 | if (pose == "FreeFall" and jumpAnimTime <= 0) then |
911 | playAnimation("fall", fallTransitionTime, Humanoid) |
912 | elseif (pose == "Seated") then |
913 | playAnimation("sit", 0.5, Humanoid) |
914 | return |
915 | elseif (pose == "Running") then |
916 | playAnimation("walk", 0.2, Humanoid) |
917 | updateVelocity(currentTime) |
918 | elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then |
919 | stopAllAnimations() |
920 | amplitude = 0.1 |
921 | frequency = 1 |
922 | setAngles = true |
923 | end |
924 | |
925 | -- Tool Animation handling |
926 | local tool = Character:FindFirstChildOfClass("Tool") |
927 | if tool and tool:FindFirstChild("Handle") then |
928 | local animStringValueObject = getToolAnim(tool) |
929 | |
930 | if animStringValueObject then |
931 | toolAnim = animStringValueObject.Value |
932 | -- message recieved, delete StringValue |
933 | animStringValueObject.Parent = nil |
934 | toolAnimTime = currentTime + .3 |
935 | end |
936 | |
937 | if currentTime > toolAnimTime then |
938 | toolAnimTime = 0 |
939 | toolAnim = "None" |
940 | end |
941 | |
942 | animateTool() |
943 | else |
944 | stopToolAnimations() |
945 | toolAnim = "None" |
946 | toolAnimInstance = nil |
947 | toolAnimTime = 0 |
948 | end |
949 | end |
950 | |
951 | |
952 | -- connect events |
953 | Humanoid.Died:connect(onDied) |
954 | Humanoid.Running:connect(onRunning) |
955 | Humanoid.Jumping:connect(onJumping) |
956 | Humanoid.Climbing:connect(onClimbing) |
957 | Humanoid.GettingUp:connect(onGettingUp) |
958 | Humanoid.FreeFalling:connect(onFreeFall) |
959 | Humanoid.FallingDown:connect(onFallingDown) |
960 | Humanoid.Seated:connect(onSeated) |
961 | Humanoid.PlatformStanding:connect(onPlatformStanding) |
962 | Humanoid.Swimming:connect(onSwimming) |
963 | |
964 | -- setup emote chat hook |
965 | game:GetService("Players").LocalPlayer.Chatted:connect(function(msg) |
966 | local emote = "" |
967 | if (string.sub(msg, 1, 3) == "/e ") then |
968 | emote = string.sub(msg, 4) |
969 | elseif (string.sub(msg, 1, 7) == "/emote ") then |
970 | emote = string.sub(msg, 8) |
971 | end |
972 | |
973 | if (pose == "Standing" and emoteNames[emote] ~= nil) then |
974 | playAnimation(emote, EMOTE_TRANSITION_TIME, Humanoid) |
975 | end |
976 | end) |
977 | |
978 | -- emote bindable hook |
979 | script:WaitForChild("PlayEmote").OnInvoke = function(emote) |
980 | -- Only play emotes when idling |
981 | if pose ~= "Standing" then |
982 | return |
983 | end |
984 | |
985 | if emoteNames[emote] ~= nil then |
986 | -- Default emotes |
987 | playAnimation(emote, EMOTE_TRANSITION_TIME, Humanoid) |
988 | |
989 | return true, currentAnimTrack |
990 | elseif typeof(emote) == "Instance" and emote:IsA("Animation") then |
991 | -- Non-default emotes |
992 | playEmote(emote, EMOTE_TRANSITION_TIME, Humanoid) |
993 | |
994 | return true, currentAnimTrack |
995 | end |
996 | |
997 | -- Return false to indicate that the emote could not be played |
998 | return false |
999 | end |
1000 | |
1001 | if Character.Parent ~= nil then |
1002 | -- initialize to idle |
1003 | playAnimation("idle", 0.1, Humanoid) |
1004 | pose = "Standing" |
1005 | end |
1006 | |
1007 | -- loop to handle timed state transitions and tool animations |
1008 | task.spawn(function() |
1009 | while Character.Parent ~= nil do |
1010 | local _, currentGameTime = wait(0.1) |
1011 | stepAnimate(currentGameTime) |
1012 | end |
1013 | end) |
1014 | end |
1015 | |
1016 | RunCustomAnimation(plr.Character) |