Compare commits

..
Author SHA1 Message Date
Paul 550b99be36 Merge remote-tracking branch 'origin/main' into lang-updates 2025-04-18 22:01:33 +10:00
Polymeta bfbee7b1d7 Merge branch 'loot-fix' into 'main'
Improved parity with vanilla mobs' drop behavior

See merge request cable-mc/cobblemon!1576
2025-04-18 07:02:45 +00:00
Test f5d71390dd Merge branch 'dex-zoom' into 'main'
A few dex scanner fixes/improvements, closes #1328

Closes #1328

See merge request cable-mc/cobblemon!1608
2025-04-18 05:06:31 +00:00
CraterandTest 6ff5d3df06 A few dex scanner fixes/improvements, closes #1328 2025-04-18 05:06:30 +00:00
gruxor 988766894a Review resolutions 2025-04-18 00:08:43 -04:00
Polymeta 34805ea496 oop typo - allow dragon breath to be used in a restoration tank
Closes #1539

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-18 00:25:39 +01:00
Polymeta b670d44e21 reorder delegate molang functions to be added first so they are overridden by more specific functions
Also allow PoseableState sound molang to play without an entity present (in UIs)

Closes #1529

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-18 00:08:59 +01:00
Polymeta 159905eb3b Merge branch 'josh/left-handed-item-fix' into 'main'
Corrected item rotation for left hand display context

See merge request cable-mc/cobblemon!1609
2025-04-17 20:32:11 +00:00
Josh c10213480b Flip rotations when display context is left hand 2025-04-17 15:22:11 -04:00
gruxor 3d5a365a6e Added a configuration option for drops' behavior upon Pokémon death 2025-04-17 14:06:33 -04:00
gruxor 4b64b4307a Changelog update 2025-04-17 14:04:16 -04:00
gruxor 382f741db8 Improved parity with vanilla mobs' drop behavior 2025-04-17 14:04:16 -04:00
TeggyandWeblate 6d62d911d6 Translated using Weblate (Spanish)
Currently translated at 96.6% (6787 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-17 11:38:28 +00:00
Alexis SalgueiroandWeblate a1d40084c5 Translated using Weblate (French)
Currently translated at 92.2% (6479 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-17 04:04:45 +00:00
TeggyandWeblate 8b1b63e110 Translated using Weblate (Spanish)
Currently translated at 96.4% (6775 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-17 04:04:44 +00:00
Polymeta baf3cd5f30 Merge branch 'moon-ball-fix-🌕🌒🌓🌔🌑🌘🌗🌖' into 'main'
Fix the messed up Moon Phase code for the Moon Ball catch rate

See merge request cable-mc/cobblemon!1605
2025-04-16 17:16:36 +00:00
Plastered_Crab 2327f1aa2c Add this to make Polymeta happy 2025-04-16 09:46:11 -07:00
plastered_crab 62036c0ac6 Fix the messed up Moon Phase code for the Moon Ball catch rate 2025-04-16 07:57:00 -07:00
TeggyandWeblate 9e2e95e287 Translated using Weblate (Spanish)
Currently translated at 96.0% (6744 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-16 09:42:42 +00:00
Landon 2db494ff5e Merge branch 'Dex-Species-Forms' into 'main'
Update English Lang with official values and preliminary species form support for the dex

See merge request cable-mc/cobblemon!1454
2025-04-16 04:43:43 +00:00
Konoha 7fe1415551 Clean InfoWidget form parsing. 2025-04-15 23:24:56 -04:00
Konoha ca4d4ed3be Re-Run Lang Key Scrape & Changelog 2025-04-15 09:02:29 -04:00
Konoha 700227be41 Merge branch 'main' into Dex-Species-Forms
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-04-15 08:39:33 -04:00
Konoha 985a4f65dc Re-Run Lang Key Scrape & Changelog 2025-04-15 08:16:41 -04:00
Konoha e117100e34 Re-Run Lang Key Scrape & Changelog 2025-04-15 08:06:10 -04:00
Konoha 93ea13fa4d Merge branch 'main' into Dex-Species-Forms 2025-04-15 07:57:01 -04:00
TeggyandWeblate 6694680c50 Translated using Weblate (Spanish)
Currently translated at 95.9% (6735 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-15 05:11:49 +00:00
Polymeta cd14881d17 Merge branch 'immersive-tweaks' into 'main'
Foods and Recipes

See merge request cable-mc/cobblemon!1554
2025-04-14 20:45:41 +00:00
dhi_holoandPolymeta 1393cc3ef3 Foods and Recipes 2025-04-14 20:45:40 +00:00
Konoha 23ebd0573a Merge branch 'implement_pokemon' into Dex-Species-Forms
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-04-14 08:05:18 -04:00
Polymeta 6447c2e2eb Merge branch 'per-world-gamerule-support' into 'main'
Add per-level gamerule support for doPokemonSpawning

See merge request cable-mc/cobblemon!1593
2025-04-14 11:32:54 +00:00
TeggyandWeblate 8cafce0a4a Translated using Weblate (Spanish)
Currently translated at 95.7% (6724 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-14 10:33:04 +00:00
BlackBeltPanda 039a18a2bf Update CHANGELOG.md 2025-04-14 04:46:06 -04:00
Watuneni iteiteandWeblate de271f81b1 Translated using Weblate (Japanese)
Currently translated at 76.4% (5365 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-04-14 06:50:20 +00:00
TeggyandWeblate feb78c5c58 Translated using Weblate (Spanish)
Currently translated at 95.3% (6698 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-14 06:50:19 +00:00
FrankTheFarmer 71736341f0 Merge branch 'main' into implement_pokemon 2025-04-14 13:55:12 +10:00
Landon bb6e5607f1 Merge branch 'stop-head-pitch' into 'main'
Make head moving actually stop this time.

See merge request cable-mc/cobblemon!1596
2025-04-13 04:55:00 +00:00
Landon 4603f5ac7a Merge branch 'riding-animation-01' into 'main'
Riding dynamic animation, riding fixes, and controller tweaks

See merge request cable-mc/cobblemon!1599
2025-04-12 23:59:31 +00:00
Jackson BowesandLandon c683294227 Riding dynamic animation, riding fixes, and controller tweaks 2025-04-12 23:59:31 +00:00
JPAK f29c2343e6 Merge remote-tracking branch 'origin/stop-head-pitch' into stop-head-pitch 2025-04-12 16:41:40 -05:00
JPAK 3a2da5a87d Make head moving actually stop this time. 2025-04-12 16:41:13 -05:00
QriviateA 27d1de8e4e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-12 17:14:04 +01:00
MiaandWeblate e5d052a6bf Translated using Weblate (German)
Currently translated at 86.7% (6090 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-04-12 10:41:09 +00:00
Landon 1c13ab24e8 Merge branch 'even-more-riding-tweaks' into 'main'
Even more riding tweaks

See merge request cable-mc/cobblemon!1597
2025-04-12 03:07:36 +00:00
Paul 380cf0ea71 You? You're meant to be dead! 2025-04-12 12:29:44 +10:00
Paul 8ded7334bb Refactor forcedTick handling in PosableEntityModel 2025-04-12 12:23:17 +10:00
QriviateA 8af62f800b Updated changelog 2025-04-12 01:27:10 +01:00
QriviateA a50da47a8e Updated Kangaskhan model + anims 2025-04-12 01:26:47 +01:00
QriviateA f690781b0d Updated Cinderace model + anims 2025-04-12 01:26:16 +01:00
FrankTheFarmer 6a7fc67ae1 Merge branch 'main' into implement_pokemon 2025-04-12 08:10:08 +10:00
Polymeta 0ac34bf1a4 Merge branch 'locator-rotation-player-rendering' into 'main'
Lock player model to seat locator's rotation when riding

See merge request cable-mc/cobblemon!1598
2025-04-11 19:41:47 +00:00
Landon Wills 9716ea0806 Fix rotation of player when using custom camera 2025-04-11 06:13:47 -04:00
Landon Wills ffea94f3b2 Rotate player depending on seat locator's rotation 2025-04-11 03:39:49 -04:00
Landon Wills 3061ba69e2 Riding momentum is maintained when window is not active 2025-04-11 03:17:26 -04:00
Landon Wills 741e38d606 Fix issue where same-species pokemon will sync animations on multiplayer environments 2025-04-11 02:01:28 -04:00
Landon Wills 02f2c072c9 Fix issues with pre-animation logic 2025-04-11 01:29:49 -04:00
JPAK 4722defec2 Make head moving actually stop this time. 2025-04-10 13:14:32 -05:00
Polymeta c54849f415 Merge branch 'implement_pokemon' into 'main'
Few mons added for testing

See merge request cable-mc/cobblemon!1595
2025-04-10 13:46:35 +00:00
Frank The FarmerandPolymeta d44e625e9d Few mons added for testing 2025-04-10 13:46:35 +00:00
FrankTheFarmer 7b7acb97d1 Changelog 2025-04-10 23:05:56 +10:00
FrankTheFarmer 53af92f254 Implemented Metagross with locators for testing 2025-04-10 23:04:07 +10:00
FrankTheFarmer 91bce4b153 Merge branch 'main' into implement_pokemon 2025-04-10 22:32:31 +10:00
BlackBeltPanda 511130d353 Remove redundant check for player UUID in spawnersForPlayers and early return in registerPlayerSpawner 2025-04-10 05:42:10 -04:00
BlackBeltPanda 476c3e54f1 Return early in CobbledWorldSpawnerManager#onDimensionChange when DO_POKEMON_SPAWNING gamerule is equal in origin and destination levels 2025-04-10 05:40:13 -04:00
Polymeta 6a74d5982a Merge branch 'more-riding-tweaks' into 'main'
Riding tweaks / fixes

See merge request cable-mc/cobblemon!1594
2025-04-10 09:13:32 +00:00
Landon Wills 03905c77d2 Add license 2025-04-10 03:12:53 -04:00
FrankTheFarmer 4bfe8b808c Implemented Magnezone with locators for testing 2025-04-10 16:36:21 +10:00
FrankTheFarmer 8db943d2a9 Merge branch 'main' into implement_pokemon 2025-04-10 16:34:54 +10:00
FrankTheFarmer fdff6ecfa5 Implemented Magnezone with locators for testing 2025-04-10 16:33:51 +10:00
BlackBeltPanda 2eb698969d Add onDimensionChange method to CobbledWorldSpawnerManager 2025-04-10 01:52:12 -04:00
BlackBeltPanda bba60f0098 Check DO_POKEMON_SPAWNING gamerule for the correct Level in SpawnerManager#onServerTick and CobbledWorldSpawnerManager#onPLayerLogin 2025-04-10 01:50:33 -04:00
BlackBeltPanda 8ee2c95853 Add unregisterPlayerSpawner and registerPlayerSpawner methods to CobbledWorldSpawnerManager 2025-04-10 01:45:43 -04:00
BlackBeltPanda 77db2ce17a Add origin and destination ServerLevel properties to ChangeDimensionEvent 2025-04-10 01:43:59 -04:00
Landon Wills da9558f5f9 Fix camera riding momentum not occurring when in chat or screens 2025-04-10 01:40:44 -04:00
Landon Wills 5c65dffac8 Improve rendering of ridden pokemon substantially on low or inconsistent FPS 2025-04-09 23:36:21 -04:00
Landon Wills b67b37c99e Fix some issues with merge 2025-04-09 22:54:23 -04:00
Landon Wills fbb7ee31c5 Merge branch 'refs/heads/main' into water-mount-behaviours 2025-04-09 22:38:45 -04:00
Polymeta d3ef26976b Merge branch 'composite-behaviour-refactor' into 'main'
Composite behaviour refactor

See merge request cable-mc/cobblemon!1584
2025-04-09 15:58:55 +00:00
Landon Wills dac01a3730 Fix issue with crashing on packet decode before player is initialized 2025-04-09 03:30:55 -04:00
Landon Wills ddb05768e4 Remove redundant riding behaviour, rename ride style option from misc to composite 2025-04-09 03:17:31 -04:00
Polymeta 5374940d24 Merge branch 'spicy-molang' into 'main'
Added `spawn_pokemon` and `attempt_wild_battle` as available MoLang functions

Closes #1237

See merge request cable-mc/cobblemon!1586
2025-04-09 07:13:00 +00:00
SpicyandPolymeta 1fd6a660dd Added spawn_pokemon and attempt_wild_battle as available MoLang functions 2025-04-09 07:13:00 +00:00
Landon Wills fd45934775 Fix issue with canRide condition, remove duplicate riding config in aerodactyl 2025-04-09 03:09:04 -04:00
Polymeta 5e0ffd8bd3 Merge branch 'josh/item-molang-fixes' into 'main'
Small fixes for molang functions related to item rendering.

See merge request cable-mc/cobblemon!1590
2025-04-08 16:02:48 +00:00
JoshandPolymeta b4b315360d Small fixes for molang functions related to item rendering. 2025-04-08 16:02:48 +00:00
Polymeta a44c70648b actually return held item to player again
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-08 16:07:20 +01:00
TeggyandWeblate 0ea4641536 Translated using Weblate (Spanish)
Currently translated at 95.3% (6696 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-08 10:41:46 +00:00
FrankTheFarmer ff5ea6fa21 Merge branch 'main' into implement_pokemon 2025-04-08 19:42:22 +10:00
FrankTheFarmer 4820d78416 Implemented Jolteon's item holding animation 2025-04-08 19:05:35 +10:00
FrankTheFarmer 2f417e953c Added placeholder cry to the eeveelution animations 2025-04-08 18:38:39 +10:00
FrankTheFarmer 8fde0ed4f6 Added rootbone and cry back to the eeveelution posers 2025-04-08 18:38:08 +10:00
FrankTheFarmer 6715874a8f Merge branch 'main' into implement_pokemon 2025-04-08 16:00:52 +10:00
RedGenesectNinja 31f88a1f68 Implemented Druddigon 2025-04-08 00:37:09 -05:00
Landon Wills 1677598ec0 Merge branch 'refs/heads/main' into water-mount-behaviours
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
2025-04-08 01:36:01 -04:00
Landon Wills 57e2765f90 Clean up some method signatures in CameraMixin 2025-04-07 21:57:20 -04:00
FrankTheFarmer f80aa2769a Restored Treecko line cries 2025-04-08 10:55:39 +10:00
FrankTheFarmer 20aa4d43b8 Delphox wand animation tweaks 2025-04-08 09:19:10 +10:00
FrankTheFarmer 9bec3e088f Changelog moment 2025-04-08 08:42:49 +10:00
FrankTheFarmer 5b4dbe1957 Imported old placeholder walk and cry for Braixen and Delphox 2025-04-08 08:36:19 +10:00
FrankTheFarmer 48f248d481 Fixed a crash caused by cosmetic remodels for Braixen and Delphox. 2025-04-08 08:36:00 +10:00
FrankTheFarmer d726c4d0ed Merge branch 'main' into implement_pokemon
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/repository/VaryingModelRepository.kt
2025-04-08 08:19:12 +10:00
FrankTheFarmer c9c421ba2a Fixed Sneasler model issues from previous update for cosmetic basket. 2025-04-07 21:00:12 +10:00
FrankTheFarmer 2436a8ddcc Fixed Tropius typo in changelog 2025-04-07 20:04:13 +10:00
FrankTheFarmer 3364944c26 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-07 19:57:12 +10:00
FrankTheFarmer 9e6a6eabc7 Fixed the wrong type of Crocs mentioned in the changelog 2025-04-07 19:55:57 +10:00
FrankTheFarmer 78def7318e Treecko my beloved. Gave json poser and fixed t-pose 2025-04-07 19:55:09 +10:00
FrankTheFarmer fdf062bd4c oops, fixed dex number for grovyle poser 2025-04-07 19:44:37 +10:00
FrankTheFarmer ef5a682adb Fixed stick related Grovyle crash and gave it a JSON poser 2025-04-07 19:41:11 +10:00
Polymeta f76d28d29e updated changelog 2025-04-07 09:35:20 +00:00
FrankTheFarmer 9c70aad64d Fixed stick related Sceptile crash and gave it a JSON poser 2025-04-07 19:17:56 +10:00
FrankTheFarmer 25de1ad180 Merge branch 'main' into implement_pokemon 2025-04-07 15:13:02 +10:00
FrankTheFarmer f967d1ec11 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-07 15:12:10 +10:00
FrankTheFarmer efd0497de1 Fixed Garchomp using battle idle in its portrait and profile 2025-04-07 15:00:47 +10:00
Kenji_64 b30c0a4a9a Adjusted Nosepass' walk speed. (Thanks Lennie and Frank!) 2025-04-06 22:21:25 +02:00
Kenji_64 c99b26a44b Added animations to Nosepass and Probopass. Made new JSON posers and replaced the Kotlin ones (thanks Lennie!) 2025-04-06 21:06:37 +02:00
FrankTheFarmer b19bc1e4c7 updated changelog 2025-04-06 21:21:37 +10:00
FrankTheFarmer bc5ffda1a5 Expedited crobat with locators 2025-04-06 21:19:09 +10:00
FrankTheFarmer 491d6c9fd6 Expedited salamence with locators 2025-04-06 21:19:01 +10:00
FrankTheFarmer ccc6ad77a5 Garchomp and perchance the craziest poser that ever lived 2025-04-06 19:47:02 +10:00
FrankTheFarmer 00fd9d1278 oopsies forgot portrait and profile data on honchkrow 2025-04-06 19:47:02 +10:00
FrankTheFarmer 01464f8b71 Expediting more models for reasons the government will not allow me to explain 2025-04-06 19:47:01 +10:00
FrankTheFarmer d91fe0b876 Merge branch 'main' into implement_pokemon 2025-04-06 18:56:00 +10:00
Landon Wills 0293c0e811 Update licenses 2025-04-06 04:02:10 -04:00
Landon Wills c7223ae898 Fix some issues with the new composite system, move assets to new system 2025-04-06 01:35:46 -04:00
Landon Wills 38f5c12dce Remove some redundant casting 2025-04-05 23:59:47 -04:00
Landon Wills e6a9a27692 Forgot to remove some code I refactored 2025-04-05 23:59:21 -04:00
Landon Wills 7ff413c401 Add support for custom behaviour settings for different composite strategies 2025-04-05 23:57:30 -04:00
Landon Wills 603f99e5f3 Refactor composite behaviours 2025-04-05 04:24:19 -04:00
Landon Wills 1b53a127af Add lapras assets 2025-04-05 01:39:02 -04:00
FrankTheFarmer 3f6faf7796 Merge branch 'main' into implement_pokemon 2025-04-05 09:24:40 +10:00
Sterrezo d5efdeee68 More adjustments to the cry checker script 2025-04-04 19:06:22 +02:00
queao 57f446260c just gonna drop these in here (added remodels for eevee and all eeveelutions) 2025-04-04 15:53:56 +10:00
Kenji_64 d4cf44f8f0 Removed the old Three Segment Aspect 2025-04-03 18:54:29 +02:00
Kenji_64 a074ebbcce It has been du-dune: Implemented Dunsparce + Dudunsparce (2 & 3 Segment Form) 2025-04-03 18:54:00 +02:00
queao 6578ed55e3 whoopsies 2025-04-03 16:12:39 +10:00
Tyzillion f567ceadd8 Implemented Cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandle line, Treecko line, Braixen, Delphox, and Dragonite.
Removed Shulker aspect and replaced it with cosmetic_item-shulker_shell.
Shulker shell Forretress is now a cosmetic rather than a special evo.
2025-04-02 18:03:11 -04:00
FrankTheFarmer 5de92f78c6 Changelog 👨‍🌾🔫🐲 2025-04-02 22:50:23 +10:00
FrankTheFarmer a2402f78e7 Added Sandaconda 🐍🐍🐍 2025-04-02 22:47:37 +10:00
FrankTheFarmer 1ad6d63137 Added Silicobra 🪱 2025-04-02 22:45:54 +10:00
FrankTheFarmer 39d417c651 Added Bronzong 👁🔔👁 2025-04-02 22:44:14 +10:00
FrankTheFarmer ce1bf9f4f2 Added Bronzor 🔷 2025-04-02 22:43:41 +10:00
FrankTheFarmer a6136906f8 Added Musharna 💤🐖 2025-04-02 22:42:44 +10:00
FrankTheFarmer 37a99b528e Added Munna 🐖 2025-04-02 22:40:46 +10:00
FrankTheFarmer 048b237302 Added Zebstrika ⚡🦓⚡ 2025-04-02 22:38:17 +10:00
FrankTheFarmer 131773f9c8 Added Blitzle ⚡🦓 2025-04-02 22:37:56 +10:00
FrankTheFarmer 22e55b7e77 Added Arboliva 🌵 2025-04-02 22:36:29 +10:00
FrankTheFarmer 6c288f9cc8 Added Dolliv 🫒🦵 2025-04-02 22:31:52 +10:00
FrankTheFarmer b5e86a9460 Added Smoliv 🫒 2025-04-02 22:30:53 +10:00
FrankTheFarmer f199e7c1c0 Added Froslass ✨👩‍🦳❄ 2025-04-02 22:29:05 +10:00
FrankTheFarmer 4161d96707 Added Glalie ⚪ 2025-04-02 22:27:35 +10:00
FrankTheFarmer 59927dd701 Added Snorunt 📐 2025-04-02 22:26:58 +10:00
FrankTheFarmer 220d8ddc0f Added Grumpig 🐖🔮 2025-04-02 22:25:53 +10:00
FrankTheFarmer 0dd143e67e Added Spoink 🔮🐷 2025-04-02 22:24:57 +10:00
FrankTheFarmer d83eb62821 Added Garbodor 🤮 2025-04-02 22:22:52 +10:00
FrankTheFarmer a716fda023 Added Trubbish 🤢 2025-04-02 22:22:25 +10:00
FrankTheFarmer d14aad787c Added Orthworm 🪱♥❓🥺 2025-04-02 22:19:01 +10:00
FrankTheFarmer 2eb7b60dd1 Added Drampa 👴🐉🔥🏠 2025-04-02 22:11:41 +10:00
TeggyandWeblate bc4699e354 Translated using Weblate (Spanish)
Currently translated at 95.1% (6683 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-02 11:09:46 +00:00
FrankTheFarmer d79ffc631b Merge branch 'main' into implement_pokemon 2025-04-02 08:41:27 +10:00
TeggyandWeblate 9270119675 Translated using Weblate (Spanish)
Currently translated at 95.1% (6682 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-31 15:23:52 +00:00
TeggyandWeblate 0058906022 Translated using Weblate (Spanish)
Currently translated at 95.1% (6678 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-31 00:16:23 +00:00
FrankTheFarmer 7cd1870f23 Merge branch 'main' into implement_pokemon 2025-03-31 07:42:53 +10:00
KyoandWeblate 14d2a76211 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-03-27 12:41:50 +00:00
Watuneni iteiteandWeblate 7669000962 Translated using Weblate (Japanese)
Currently translated at 76.3% (5358 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-27 12:41:46 +00:00
Sterrezo 716d1b848e Fixed and renamed cries for Galarian Ponyta, Galarian Rapidash and Alolan Raichu 2025-03-26 16:19:26 +01:00
Sterrezo 4878fc517d Updated and cleaned up the cry checker script 2025-03-26 16:00:57 +01:00
Sterrezo 4d9d543110 STOP BREAKING THE SPREADSHEET
fixed script
2025-03-26 14:26:15 +01:00
FrankTheFarmer 718a9b922b Merge branch 'main' into implement_pokemon 2025-03-26 08:28:53 +10:00
GenotypeXD-Dev e2a152aeb3 Model Fixes didnt push 2025-03-24 19:34:11 -06:00
GenotypeXD-Dev 3e21226b27 Implemented Hawlucha + fixed z fighting on Noibat and scaled down to 0.6 2025-03-24 19:30:16 -06:00
queao c46c5b806c IT'S TIIIIIIIIIIME (implemented noibat and noivern - implementation work done by genotype) 2025-03-24 18:49:07 +10:00
FrankTheFarmer 3c37d93046 Merge branch 'main' into implement_pokemon 2025-03-24 16:40:53 +10:00
TeggyandWeblate 8912911800 Translated using Weblate (Spanish)
Currently translated at 94.3% (6621 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-22 01:16:22 +00:00
阿鱼andWeblate 62ecfaf54a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-20 23:47:02 +00:00
TeggyandWeblate 6684177236 Translated using Weblate (Spanish)
Currently translated at 94.2% (6615 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-20 23:47:00 +00:00
Watuneni iteiteandWeblate deca5cf55b Translated using Weblate (Japanese)
Currently translated at 76.1% (5350 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-20 23:46:59 +00:00
FrankTheFarmer 7b2790de50 Changelog setup for 1.7 implementation stuff 2025-03-18 09:20:30 +10:00
FrankTheFarmer 7f2bb84c85 Merge branch 'main' into implement_pokemon 2025-03-18 09:12:06 +10:00
阿鱼andWeblate 0f75797759 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-17 21:03:49 +00:00
FrankTheFarmer 331e1371d4 Illegal imports of Dragonite and Gyarados models with locators for testing 2025-03-16 09:42:56 +10:00
FrankTheFarmer bdd57ba1a4 Merge branch 'main' into implement_pokemon 2025-03-16 08:53:37 +10:00
Alexis SalgueiroandWeblate c194aefce5 Translated using Weblate (French)
Currently translated at 91.5% (6425 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-15 14:17:58 +00:00
Aiser(CCHusky)andWeblate f4798c8783 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-15 14:17:57 +00:00
chronicenandWeblate 2178a5f10e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-15 14:17:57 +00:00
TeggyandWeblate bc145a56d5 Translated using Weblate (Spanish)
Currently translated at 93.6% (6575 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-14 17:00:49 +00:00
FrankTheFarmer 670e7e9ca1 Merge branch 'main' into implement_pokemon 2025-03-13 13:55:26 +10:00
Nico MerenqandWeblate 476ef3bb2f Translated using Weblate (Russian)
Currently translated at 73.9% (5189 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-12 13:19:09 +00:00
Alexis SalgueiroandWeblate 460050289b Translated using Weblate (French)
Currently translated at 90.7% (6373 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-10 15:04:25 +00:00
Nico MerenqandWeblate 01fd4dcc68 Translated using Weblate (Russian)
Currently translated at 73.8% (5182 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-09 18:06:58 +00:00
Nico MerenqandWeblate 0392eb3b7e Translated using Weblate (Russian)
Currently translated at 73.6% (5172 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-09 15:29:58 +00:00
阿鱼andWeblate 493f423a2f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-09 10:54:04 +00:00
阿鱼andWeblate cbcfa1bbfb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-09 10:45:17 +00:00
Nico MerenqandWeblate 17a3ff15db Translated using Weblate (Russian)
Currently translated at 73.6% (5171 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-09 10:30:06 +00:00
阿鱼andWeblate 9c14cccc98 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (7017 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-09 10:30:05 +00:00
Weblate 850cfbe755 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-03-08 22:51:12 +00:00
TeggyandWeblate 28afa6a9e8 Translated using Weblate (Spanish)
Currently translated at 93.1% (6538 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-08 22:51:08 +00:00
阿鱼andWeblate 7a76d95ce7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.7% (6936 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 22:51:07 +00:00
TeggyandWeblate 54707d0618 Translated using Weblate (Spanish)
Currently translated at 92.1% (6470 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-08 15:08:19 +00:00
Aiser(CCHusky)andWeblate 307c400e28 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.6% (6929 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 15:08:18 +00:00
阿鱼andWeblate 5c9b3ab25d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.6% (6929 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 15:08:18 +00:00
阿鱼andWeblate 532e991fb2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.1% (6890 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 11:31:35 +00:00
Nico MerenqandWeblate b1bf817329 Translated using Weblate (Russian)
Currently translated at 73.6% (5171 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-08 11:31:34 +00:00
TeggyandWeblate c091f90487 Translated using Weblate (Spanish)
Currently translated at 91.7% (6445 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-08 08:23:13 +00:00
阿鱼andWeblate a49d4715ff Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.0% (6816 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 08:23:12 +00:00
阿鱼andWeblate 652b15532e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.9% (6807 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-07 04:18:30 +00:00
TeggyandWeblate e4064897b0 Translated using Weblate (Spanish)
Currently translated at 91.5% (6430 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-07 04:18:29 +00:00
阿鱼andWeblate f9ca8222da Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.7% (6793 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-06 12:30:15 +00:00
FrankTheFarmer 3ae349aea5 Merge branch 'main' into implement_pokemon 2025-03-06 18:28:14 +10:00
阿鱼andWeblate 67480a945f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.5% (6708 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-06 06:42:04 +00:00
Alexis SalgueiroandWeblate e6e811e6e6 Translated using Weblate (French)
Currently translated at 90.0% (6320 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-06 06:41:58 +00:00
Watuneni iteiteandWeblate 4635c531b9 Translated using Weblate (Japanese)
Currently translated at 73.7% (5178 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-06 06:41:56 +00:00
Watuneni iteiteandWeblate 3bdfac9a46 Translated using Weblate (Japanese)
Currently translated at 71.7% (5039 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-05 13:53:19 +00:00
chronicenandWeblate 2b7a71cb1c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 91.4% (6424 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-05 13:53:19 +00:00
阿鱼andWeblate d47a500a0e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 91.4% (6424 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-05 13:53:19 +00:00
FrankTheFarmer 13650f98f9 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-03-05 14:23:08 +10:00
FrankTheFarmer d3379557fd 2 more Gen 5 monkeys jumping on the bed 2025-03-05 14:22:28 +10:00
FrankTheFarmer 143c2683fe Added placeholder animations to Pansage and Simisage 2025-03-05 14:21:54 +10:00
FrankTheFarmer 72d64d36e5 Changed panpour scale and hitbox size to match that of the other monkeys 2025-03-05 14:21:17 +10:00
Wi2tert c0b52c38e3 "implemented": Panpour、Simipour 💧🐒 2025-03-05 12:11:22 +08:00
FrankTheFarmer 12a0ee309e Merge branch 'main' into implement_pokemon 2025-03-05 08:01:14 +10:00
阿鱼andWeblate 33e6dbb4c1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 87.4% (6143 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-04 15:50:25 +00:00
RedGenesectNinja 824e37effd Implemented Pansage and Simisage 2025-03-03 23:12:27 -06:00
Alexis SalgueiroandWeblate 482c57dd2e Translated using Weblate (French)
Currently translated at 89.1% (6259 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-03 19:14:47 +00:00
Alexis SalgueiroandWeblate 503c62d78d Translated using Weblate (French)
Currently translated at 87.8% (6169 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-03 09:30:43 +00:00
Seonho LeeandWeblate 708d0ab6d3 Translated using Weblate (Korean)
Currently translated at 70.0% (4915 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-03-03 09:30:42 +00:00
TeggyandWeblate 19727542bd Translated using Weblate (Spanish)
Currently translated at 91.4% (6424 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-28 22:02:07 +00:00
Alexis SalgueiroandWeblate c4e6714a95 Translated using Weblate (French)
Currently translated at 87.6% (6153 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-02-28 02:41:41 +00:00
TeggyandWeblate c116e612c6 Translated using Weblate (Spanish)
Currently translated at 90.4% (6354 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-28 02:41:41 +00:00
Fiestorra ISVandWeblate 215a055ce6 Translated using Weblate (Spanish)
Currently translated at 90.4% (6354 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-28 02:41:40 +00:00
Fiestorra ISVandWeblate 9c0b6b8d26 Translated using Weblate (Spanish)
Currently translated at 87.3% (6134 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-25 22:27:22 +00:00
Fiestorra ISVandWeblate 5c4462ee94 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-25 18:48:01 +00:00
TeggyandWeblate 04edd6f9e2 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-25 18:48:01 +00:00
Polymeta 52821cc051 Merge branch 'main' into lang-updates 2025-02-25 18:38:33 +00:00
Watuneni iteiteandWeblate 0029deb029 Translated using Weblate (Japanese)
Currently translated at 81.6% (5218 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-02-23 23:03:25 +00:00
TeggyandWeblate c6360e2a36 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-23 23:03:24 +00:00
Fiestorra ISVandWeblate 2e77c647b6 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-23 23:03:22 +00:00
Watuneni iteiteandWeblate c3d3b19788 Translated using Weblate (Japanese)
Currently translated at 81.3% (5200 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-02-21 08:11:08 +00:00
Fiestorra ISVandWeblate 219cd61beb Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-21 08:11:07 +00:00
TeggyandWeblate 207e5a9142 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-19 13:03:51 +00:00
Watuneni iteiteandWeblate c721fb534d Translated using Weblate (Japanese)
Currently translated at 81.2% (5191 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-02-18 15:00:29 +00:00
iván SeguraandWeblate dba2622fd7 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-18 15:00:28 +00:00
iván SeguraandWeblate da68675133 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-16 12:57:27 +00:00
Kenji_64 975cdf050f Fixed Charcadet's cry sound event not being there and head pivot 2025-02-15 15:34:34 +01:00
iván SeguraandWeblate 9aea5a7daf Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-15 13:26:10 +00:00
Gustavo PuerariandWeblate 10402575fb Translated using Weblate (Portuguese (Brazil))
Currently translated at 68.3% (4369 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-13 23:43:36 +00:00
João Pedro Silva AfonsoandWeblate 0f82ade57c Translated using Weblate (Portuguese (Brazil))
Currently translated at 68.3% (4369 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-13 23:43:35 +00:00
Gustavo PuerariandWeblate 450b041118 Translated using Weblate (Portuguese (Brazil))
Currently translated at 65.1% (4166 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-11 21:12:32 +00:00
Weblate 770c349ac4 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-02-10 00:41:50 +00:00
Gustavo PuerariandWeblate f76648b6f2 Translated using Weblate (Portuguese (Brazil))
Currently translated at 59.8% (3826 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-10 00:41:46 +00:00
Gustavo PuerariandWeblate 56e60667db Translated using Weblate (Portuguese (Brazil))
Currently translated at 51.5% (3297 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-07 00:29:47 +00:00
Gustavo PuerariandWeblate c4a60951c5 Translated using Weblate (Portuguese (Brazil))
Currently translated at 49.7% (3178 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-05 07:22:58 +00:00
KyoandWeblate 814eee8125 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-02-03 09:44:44 +00:00
Gustavo PuerariandWeblate 2a9ff3bfbd Translated using Weblate (Portuguese (Brazil))
Currently translated at 47.9% (3064 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-03 09:44:43 +00:00
Konoha 8fe2042127 Merge Basculin game evolutions 2025-02-02 08:17:05 -05:00
Konoha 538ad883ab Correct Spewpa evo tag reference in evolution to tag format 2025-02-02 08:02:49 -05:00
Konoha 136cb86492 Correct the consumption of held items on non-applicable item evolutions 2025-02-01 08:22:12 -05:00
Konoha e4eb1251d1 Fix Goomy & Bergmite branch evolutions, branching stone anticondition conflict. 2025-02-01 07:51:39 -05:00
Weblate 83350cb0db Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-01-31 22:57:44 +00:00
Patch Notes GuyandWeblate 778761dbee Translated using Weblate (Vietnamese)
Currently translated at 99.1% (6335 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-01-31 22:57:39 +00:00
Gustavo PuerariandWeblate e9881b748a Translated using Weblate (Portuguese (Brazil))
Currently translated at 46.4% (2971 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-01-31 22:57:25 +00:00
Weblate dabaeefa23 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-01-31 09:41:51 +00:00
Patch Notes GuyandWeblate 0e0bec2712 Added translation using Weblate (Vietnamese) 2025-01-31 09:41:47 +00:00
Gustavo PuerariandWeblate 48fe160334 Translated using Weblate (Portuguese (Brazil))
Currently translated at 45.1% (2887 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-01-31 03:10:48 +00:00
Valerie Rice 1bc83d9045 poison frog man (only the little one) 2025-01-28 16:22:21 +10:00
Gustavo PuerariandWeblate 7d599e12d0 Translated using Weblate (Portuguese (Brazil))
Currently translated at 42.7% (2731 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-01-27 23:30:11 +00:00
Konoha 98775ffc1e Merge branch 'main' into Dex-Species-Forms
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-01-27 09:26:48 -05:00
Konoha bbeb3d45f0 Merge branch 'implement_pokemon' into Dex-Species-Forms 2025-01-21 11:37:28 -05:00
Konoha 8fd854f7f7 Merge branch 'main' into Dex-Species-Forms 2025-01-18 16:48:07 -05:00
Konoha f449cf27c5 Merge branch 'implement_pokemon' into Dex-Species-Forms 2025-01-18 10:59:31 -05:00
Konoha bf5fd5eed8 Merge remote-tracking branch 'origin/main' 2025-01-03 19:19:26 -05:00
Konoha facead5f0b Preliminary species form support for Pokedex 2025-01-03 19:12:31 -05:00
312 changed files with 41574 additions and 10729 deletions
+42 -4
View File
@@ -13,7 +13,12 @@
- Added `visibility/hidden`, `visibility/hat` and `visibility/face` tags to control where and how certain items are rendered.
- Added Pokémon markings, toggleable within the summary.
- Added `/boxcount` command to change PC boxes amount
- Added cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandile line, Treecko line, Braixen, Delphox, and Dragonite.
- Added cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandle line, Treecko line, Braixen, Delphox, and Dragonite.
- Added `/transformmodelpart (position|rotation|scale) <modelPart> <transform: x y z>` command that can add transformations to a pokemon's model part.
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
- Added lang keys for all moves and abilities up to Generation 9.
- Fixed Moon Ball moon phase logic to actually work correctly
### Pokémon Added
@@ -66,9 +71,15 @@
### Animation updates for the following Pokémon
- Garchomp
- Tropius
- Torpius
- Nosepass
- Probopass
- Sneasler
- Braixen
- Delphox
- Cinderace
- Kangaskhan
### Model updates for the following Pokémon
- Gyarados
@@ -82,23 +93,43 @@
- Leafeon
- Glaceon
- Sylveon
- Treecko
- Grovyle
- Sceptile
- Honchkrow
- Garchomp
- Pidgeot
- Nosepass
- Probopass
- Added `/transformmodelpart (position|rotation|scale) <modelPart> <transform: x y z>` command that can add transformations to a pokemon's model part.
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
- Kangaskhan
- Cinderace
- Magnezone
- Metagross
- Added Syrupy Apples.
### Changes
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
- Made Blocks of Gold count as Big Nuggets when held by a Pokémon (for Fling functionality)
- Players can now eat Sweet and Tart Apples, Whipped Dreams, and the Alcremie Sweets.
- Updated Sweet and Tart Apple sprites
- Updated the following recipes: Air Balloon, Assault Vest, Binding Band, Black Belt, Blunder Policy, Choice Band, Choice Scarf, Cleanse Tag, Covert Cloak, Destiny Knot, Eject Button, Expert Belt, Focus Band, Focus Sash, Magnet, Metronome, Muscle Band, Power Anklet, Power Band, Power Belt, Power Bracer, Power Lens, Power Weight, Protective Pads, Protein, Punching Glove, Reaper Cloth, Rocky Helmet, Room Service, Sachet, Safety Goggles, Silk Scarf, Spell Tag, Utility Umbrella, Weakness Policy, Zinc
- Added alternate ingredient options to the following recipes: Cell Battery, Charcoal Stick, Dragon Fang, Miracle Seed, Mystic Water, Never Melt Ice, Twisted Spoon, Damp Rock, Heat Rock, Icy Rock, Smooth Rock
- Grouped together some recipes within the Recipe Book. Groups include: the seven basic Poké Balls, the seven basic Ancient Poké Balls, Gilded Chests, Pokedexes, and the Weather Rocks.
- Updated some item tags to better integrate behaviours between Cobblemon, Vanilla Minecraft, and other mods
- Removed Cooked Meat, Raw Meat, Protein Ingredients, and Zinc Ingredients, the first two are now using `c` namespace tags, the latter have better integrated use of tags within their recipes which removes need for custom tags.
- Added our seeds tag into `#c:seeds`, which is now made use of for the Miracle Seed recipe.
- Tweaked the Natural Materials Vanilla file to fit with the changes to tags
- Substantially optimised spawning checks mainly by front-loading biome filtering.
- When using the `cobblemon` or `generation_9` capture calculators a critical capture with a single shake will always play for successful captures when you've already registered the Pokémon as caught in your Pokédex.
- Improved the performance of saving Pokédex and player data.
- Pokémon hitbox now scales with entity attribute `generic.scale`.
- Removed Shulker aspect and replaced it with cosmetic_item-shulker_shell.
- Shulker shell Forretress is now a cosmetic rather than a special evo and thus all shulker Forretress will revert back to normal until a shulker shell is put in their cosmetic slot.
- Updated `doPokemonSpawning` gamerule to support per-dimension configurations.
- The Pokedex now displays a form name of a "normal" Pokémon for when the base form is still a named form.
- Improved the zoom functionality of the Pokédex Scanner by giving the levels logarithmic scaling.
- Added a subtle rotation effect to the Pokédex Scanner's wheel when zooming.
- Improved parity with vanilla mobs' drop behavior; loot and XP drop on death instead of after the entire death sequence finishes.
### Fixes
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
@@ -127,7 +158,9 @@
- Fixed Pokémon marked as silent still playing shiny sounds and effects.
- Fixed an issue with newer versions of Fabric API where underground Pokémon were spawning in The End.
- Fixed spawning not working well when you're at high points surrounded by lower altitude spawning areas, such as flying.
- Fixed swapping held items with wild Pokémon under certain circumstances causing duplicate items
- Fixed certain Pokémon with forms not having appropriate stock Pokédex entries.
- Fixed issue with Pokédex Scanner that caused the open/close overlay to have the wrong opacity values
- Fixed dragon's breath not being usable on the restoration tank when it should be
### Developer
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
@@ -156,11 +189,15 @@
- Added `interpolate` boolean property to animated textures to allow gradual colour changes between frames.
- Fixed species additions not being capable of changing implemented status.
- Added support for action effects that are triggered by `|-activate|` Showdown instructions. `activate_{effect_id}` is the syntax.
- Added Molang functions for rendering items `render_item(item_id, locator_name)` and `clear_items()`.
- Added MoLang functions for rendering items `render_item(item_id, locator_name)` and `clear_items()`.
- Fixed location spawn filter components causing crashes
- Added `pokemon` as an available MoLang function for the `battleActor` functions.
- Added `spawn_pokemon` as an available MoLang function for the `worldHolder` functions.
- Added `attempt_wild_battle` as an available MoLang function.
- Added `pokemon` as an available Molang function for the `battleActor` functions.
- Fixed `heldItem` property inside spawn files not working and causing crashes
- Fixed `spawn_bedrock_particles` MoLang causing crashes when used in a server environment
- The Pokédex form lang key definition now follows `cobblemon.ui.pokedex.info.form.{species}-{formname}` instead of `cobblemon.ui.pokedex.info.form.{formname}`.
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -266,6 +303,7 @@
- Geodude
- Graveler
- Golem
- Magnezone
### Cry updates for the following Pokémon
- Sceptile
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.riding.Rideable;
import com.cobblemon.mod.common.api.riding.Seat;
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController;
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
import com.cobblemon.mod.common.client.render.MatrixWrapper;
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState;
@@ -60,6 +61,8 @@ public abstract class CameraMixin {
@Shadow
private BlockGetter level;
@Shadow private float partialTickTime;
@Unique private float returnTimer = 0;
@Unique private float rollAngleStart = 0;
@Unique Minecraft minecraft = Minecraft.getInstance();
@@ -67,7 +70,7 @@ public abstract class CameraMixin {
@Unique boolean disableRollableCameraDebug = false;
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void open_camera$setRotation(float f, float g, CallbackInfo ci) {
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
if (!(this.entity instanceof OrientationControllable controllable) || disableRollableCameraDebug) return;
var controller = controllable.getOrientationController();
if (!controller.isActive() && controller.getOrientation() != null) {
@@ -85,7 +88,7 @@ public abstract class CameraMixin {
return;
}
controller.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart*(1-returnTimer)));
applyRotation();
cobblemon$applyRotation();
this.returnTimer += .05F;
ci.cancel();
} else {
@@ -95,7 +98,7 @@ public abstract class CameraMixin {
return;
}
if (controller.getOrientation() == null) return;
applyRotation();
cobblemon$applyRotation();
this.returnTimer = 0;
this.rollAngleStart = controller.getRoll();
@@ -104,9 +107,10 @@ public abstract class CameraMixin {
//If you want to move this to a delagate you need an AW for position
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setPosition(DDD)V"))
public void positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
public void cobblemon$positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
MountedPokemonAnimationRenderController.INSTANCE.reset();
if(vehicle instanceof Rideable){
//RidingCameraDelagate.INSTANCE.positionCamera(instance, x, y, z, original);
@@ -115,20 +119,20 @@ public abstract class CameraMixin {
return;
}
int seatIndex = pokemon.getPassengers().indexOf(entity);
Seat seat = pokemon.getSeats().get(seatIndex);
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemon.getDelegate();
Vec3 entityPos = new Vec3(
Mth.lerp(instance.getPartialTickTime(), pokemon.xOld, pokemon.getX()),
Mth.lerp(instance.getPartialTickTime(), pokemon.yOld, pokemon.getY()),
Mth.lerp(instance.getPartialTickTime(), pokemon.zOld, pokemon.getZ())
);
MountedPokemonAnimationRenderController.INSTANCE.setup(pokemon, partialTickTime);
int seatIndex = pokemon.getPassengers().indexOf(entity);
Seat seat = pokemon.getSeats().get(seatIndex);
OrientationControllable rollable = (OrientationControllable) entity;
OrientationController controller = rollable.getOrientationController();
if (!instance.isDetached() || Cobblemon.config.getThirdPartyViewBobbing()) {
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemon.getDelegate();
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
if (locator == null) {
@@ -139,10 +143,12 @@ public abstract class CameraMixin {
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
float currEyeHeight = Mth.lerp(instance.getPartialTickTime(), eyeHeightOld, eyeHeight);
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(new Vector3f(0f, currEyeHeight - (entity.getBbHeight() / 2), 0f)));
var rotatedEyeHeight = new Vector3f(0f, currEyeHeight - (entity.getBbHeight() / 2), 0f);
if (controller.isActive()) {
rotatedEyeHeight = controller.getRenderOrientation(partialTickTime).transform(rotatedEyeHeight);
}
Vec3 position = locatorOffset.add(entityPos).add(rotatedEyeHeight);
Vec3 position = locatorOffset.add(entityPos).add(new Vec3(rotatedEyeHeight));
setPosition(position);
} else {
Vector3f pos = entityPos.add(new Vec3(0, pokemon.getBbHeight() / 2, 0)).toVector3f();
@@ -179,7 +185,7 @@ public abstract class CameraMixin {
}
@Unique
private void applyRotation(){
private void cobblemon$applyRotation(){
if (!(this.entity instanceof OrientationControllable controllable) || controllable.getOrientationController().getOrientation() == null) return;
var controller = controllable.getOrientationController();
var newRotation = controller.getOrientation().normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
@@ -59,8 +59,21 @@ public class HumanoidModelMixin {
}
Entity vehicle = entity.getVehicle();
if (vehicle instanceof PokemonEntity && entity instanceof AbstractClientPlayer) {
MountedPlayerRenderer.INSTANCE.animate((PokemonEntity) vehicle, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
if (vehicle instanceof PokemonEntity pokemonEntity && entity instanceof AbstractClientPlayer) {
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRotatePlayerHead(settings, state, pokemonEntity);
});
if (!shouldRotatePlayerHead) {
netHeadYaw = 0f;
headPitch = 0f;
if (this.head != null) {
this.head.yRot = 0f;
this.head.xRot = 0f;
}
}
MountedPlayerRenderer.INSTANCE.animate(pokemonEntity, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
}
}
}
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.Blaze3D;
import net.minecraft.client.Minecraft;
import net.minecraft.client.MouseHandler;
import net.minecraft.client.player.LocalPlayer;
@@ -29,9 +30,10 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(MouseHandler.class)
public class MouseHandlerMixin {
public abstract class MouseHandlerMixin {
@Shadow private double accumulatedScrollY;
@Shadow @Final private Minecraft minecraft;
@@ -49,6 +51,14 @@ public class MouseHandlerMixin {
@Shadow private double accumulatedDY;
@Shadow private double lastHandleMovementTime;
@Shadow public abstract boolean isMouseGrabbed();
@Shadow protected abstract void turnPlayer(double movementTime);
@Unique private double cobblemon$timeDelta;
@Inject(
method = "onScroll",
at = @At(
@@ -161,16 +171,21 @@ public class MouseHandlerMixin {
return false;
}
@Inject(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;isMouseGrabbed()Z", ordinal = 0))
private void cobblemon$maintainMovementWhenInScreens(CallbackInfo ci, @Local(ordinal = 1) double e) {
@Inject(method = "handleAccumulatedMovement", at = @At("HEAD"))
private void cobblemon$maintainMovementWhenInScreens2(CallbackInfo ci) {
double time = Blaze3D.getTime();
cobblemon$timeDelta = time - this.lastHandleMovementTime;
}
@Inject(method = "handleAccumulatedMovement", at = @At("TAIL"))
private void cobblemon$maintainMovementWhenInScreens(CallbackInfo ci) {
if (minecraft.player == null) return;
if (!(minecraft.player instanceof OrientationControllable controllable)) return;
if (!controllable.getOrientationController().isActive()) return;
if (minecraft.isPaused()) return;
if (isMouseGrabbed()) return;
var pitch = pitchSmoother.getNewDeltaValue(0, e);
var roll = rollSmoother.getNewDeltaValue(0, e);
controllable.getOrientationController().rotate(0.0F, (float)pitch, (float)roll);
this.turnPlayer(cobblemon$timeDelta);
}
@Unique
@@ -1,38 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerModel.class)
public class PlayerModelMixin {
@Inject(method = "setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V", at = @At(value = "HEAD"))
private void cobblemon$setHeadRotation(LivingEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, CallbackInfo ci) {
if (!(entity instanceof Player)) return;
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof PokemonEntity pokemonEntity)) return;
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRotatePlayerHead(settings, state, pokemonEntity);
});
if (shouldRotatePlayerHead) return;
netHeadYaw = 0f;
headPitch = 0f;
}
}
@@ -293,20 +293,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val REAPER_CLOTH = noSettingsItem("reaper_cloth")
@JvmField val PRISM_SCALE = noSettingsItem("prism_scale")
@JvmField val SACHET = noSettingsItem("sachet")
@JvmField val WHIPPED_DREAM = noSettingsItem("whipped_dream")
@JvmField val STRAWBERRY_SWEET = noSettingsItem("strawberry_sweet")
@JvmField val LOVE_SWEET = noSettingsItem("love_sweet")
@JvmField val BERRY_SWEET = noSettingsItem("berry_sweet")
@JvmField val CLOVER_SWEET = noSettingsItem("clover_sweet")
@JvmField val FLOWER_SWEET = noSettingsItem("flower_sweet")
@JvmField val STAR_SWEET = noSettingsItem("star_sweet")
@JvmField val RIBBON_SWEET = noSettingsItem("ribbon_sweet")
@JvmField val WHIPPED_DREAM = create("whipped_dream", foodItem(8, 0.3f))
@JvmField val STRAWBERRY_SWEET = create("strawberry_sweet", foodItem(6, 0.125f))
@JvmField val LOVE_SWEET = create("love_sweet", foodItem(6, 0.125f))
@JvmField val BERRY_SWEET = create("berry_sweet", foodItem(6, 0.125f))
@JvmField val CLOVER_SWEET = create("clover_sweet", foodItem(6, 0.125f))
@JvmField val FLOWER_SWEET = create("flower_sweet", foodItem(6, 0.125f))
@JvmField val STAR_SWEET = create("star_sweet", foodItem(6, 0.125f))
@JvmField val RIBBON_SWEET = create("ribbon_sweet", foodItem(6, 0.125f))
@JvmField val CHIPPED_POT = noSettingsItem("chipped_pot")
@JvmField val CRACKED_POT = noSettingsItem("cracked_pot")
@JvmField val MASTERPIECE_TEACUP = noSettingsItem("masterpiece_teacup")
@JvmField val UNREMARKABLE_TEACUP = noSettingsItem("unremarkable_teacup")
@JvmField val SWEET_APPLE = noSettingsItem("sweet_apple")
@JvmField val TART_APPLE = noSettingsItem("tart_apple")
@JvmField val SWEET_APPLE = create("sweet_apple", foodItem(4, 0.3f))
@JvmField val TART_APPLE = create("tart_apple", foodItem(4, 0.3f))
@JvmField val SYRUPY_APPLE = create("syrupy_apple", foodItem(4, 0.3f))
@JvmField val GALARICA_CUFF = noSettingsItem("galarica_cuff")
@JvmField val GALARICA_WREATH = noSettingsItem("galarica_wreath")
@JvmField val BLACK_AUGURITE = noSettingsItem("black_augurite")
@@ -1358,4 +1359,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return createdItem
}
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
return Item(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
}
}
@@ -20,4 +20,4 @@ interface EntitySideDelegate<T : Entity> {
fun tick(entity: T) {}
fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {}
fun addToStruct(struct: QueryStruct) {}
}
}
@@ -22,4 +22,5 @@ interface PokemonSideDelegate : EntitySideDelegate<PokemonEntity> {
fun handleStatus(status: Byte) {}
fun spawnShinyParticle(player: Player) {}
fun positionRider(passenger: Entity, positionUpdater: MoveFunction)
}
fun updateAge(age: Int) {}
}
@@ -38,6 +38,7 @@ import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
import com.cobblemon.mod.common.api.storage.pc.PCPosition
import com.cobblemon.mod.common.api.storage.pc.PCStore
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
@@ -293,6 +294,27 @@ object MoLangFunctions {
packet.sendToPlayersAround(x, y, z, 64.0, world.dimension())
}
}
map.put("spawn_pokemon") { params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val props = params.getString(3).toProperties()
val pos = BlockPos(x, y, z)
if (!Level.isInSpawnableBounds(pos)) {
return@put DoubleValue.ZERO
}
val pokemon = props.createEntity(world)
pokemon.moveTo(pos, pokemon.yRot, pokemon.xRot)
if (world.addFreshEntity(pokemon)) {
return@put pokemon.struct
} else {
return@put DoubleValue.ZERO
}
}
map.put("get_entities_around") { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
@@ -810,9 +832,14 @@ object MoLangFunctions {
map.put("is_moving") { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map.put("is_gliding") { DoubleValue(pokemonEntity.useRidingAltPose()) }
map.put("is_ridden") { DoubleValue(pokemonEntity.hasControllingPassenger()) }
map.put("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
map.put("is_pokemon") { DoubleValue.ONE }
map.put("is_holding_item") { DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).isEmpty) }
map.put("is_holding_item") { DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
}) }
map.put("is_wearing_hat") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)) }
map.put("is_wearing_face") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)) }
map
}
)
@@ -19,4 +19,4 @@ interface Decodable {
*/
fun decode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -25,4 +25,4 @@ interface Encodable {
*/
fun encode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -107,4 +107,22 @@ open class OrientationController(val entity: LivingEntity) {
val roll: Float
get() = Mth.wrapDegrees(-upVector.angleSigned(UP, forwardVector).toDegrees())
fun applyGlobalYaw(deltaYawDegrees: Float) = updateOrientation { original ->
val euler = Vector3f()
original.getEulerAnglesXYZ(euler)
val pitch0 = euler.x
val roll0 = euler.z
val unroll = Matrix3f().rotateZ(-roll0)
val unpitch = Matrix3f().rotateX(-pitch0)
val flattened = Matrix3f(original).mul(unroll).mul(unpitch)
//Flip to reflect current acceptance of what direction is pos for yaw
val globalYaw = Matrix3f().rotationY(-1.0f * deltaYawDegrees.toRadians())
val rePitch = Matrix3f().rotateX(pitch0)
val reRoll = Matrix3f().rotateZ(roll0)
return@updateOrientation Matrix3f(globalYaw).mul(flattened).mul(rePitch).mul(reRoll)
}
}
@@ -77,18 +77,18 @@ object CatchRateModifiers {
/**
* Used by [PokeBalls.MOON_BALL].
* Boosts the catch rate 1.5× during Moon Phases 3 and 7 between the times of 12000 – 24000.
* 2.5× during Moon Phases 2 and 8 between the times of 12000 – 24000.
* 4× during Moon Phase 1 between the times of 12000 – 24000.
* Boosts the catch rate 1.5× during Moon Phases 2 and 6 between the times of 12000 – 24000.
* 2.5× during Moon Phases 1 and 7 between the times of 12000 – 24000.
* 4× during Moon Phase 0 between the times of 12000 – 24000.
* 1× otherwise.
*/
val MOON_PHASES: CatchRateModifier = WorldStateModifier { _, entity ->
if (entity.level().gameTime in 12000..24000)
return@WorldStateModifier 1F
when (entity.level().moonPhase) {
3, 7 -> 1.5F
2, 8 -> 2.5F
1 -> 4F
2, 6 -> 1.5F
1, 7 -> 2.5F
0 -> 4F
else -> 1F
}
}
@@ -41,9 +41,6 @@ class RidingProperties(
}
}
val canRide: Boolean
get() = seats.isNotEmpty() && behaviour != null
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeMap(
stats,
@@ -53,7 +50,6 @@ class RidingProperties(
buffer.writeCollection(seats) { _, seat -> seat.encode(buffer) }
buffer.writeCollection(conditions) { _, condition -> buffer.writeString(condition.getString()) }
buffer.writeNullable(behaviour) { _, behaviour ->
buffer.writeResourceLocation(behaviour.key)
behaviour.encode(buffer)
}
}
@@ -18,5 +18,6 @@ package com.cobblemon.mod.common.api.riding
enum class RidingStyle {
LAND,
LIQUID,
AIR
}
AIR,
COMPOSITE
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
@@ -27,6 +28,7 @@ import net.minecraft.world.phys.Vec3
*/
interface RidingBehaviour<Settings : RidingBehaviourSettings, State : RidingBehaviourState> {
val key: ResourceLocation
val style: RidingStyle
fun isActive(settings: Settings, state: State, vehicle: PokemonEntity): Boolean
@@ -85,6 +87,6 @@ interface RidingBehaviour<Settings : RidingBehaviourSettings, State : RidingBeha
fun shouldRotatePlayerHead(settings: Settings, state: State, vehicle: PokemonEntity): Boolean
fun createDefaultState(): State
fun createDefaultState(settings: Settings): State
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.phys.Vec3
/**
* Represents static settings of a riding behaviour.
@@ -8,15 +8,10 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.ifClient
import com.cobblemon.mod.common.util.ifServer
import net.minecraft.client.player.RemotePlayer
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import kotlin.reflect.KProperty
import net.minecraft.world.phys.Vec3
/**
* Represents the state of a Pokemon when being ridden.
@@ -27,18 +22,38 @@ import kotlin.reflect.KProperty
*
* @author landonjw
*/
interface RidingBehaviourState : Encodable, Decodable {
fun reset()
fun copy(): RidingBehaviourState
fun shouldSync(previous: RidingBehaviourState): Boolean
}
open class RidingBehaviourState {
open val rideVelocity: SidedRidingState<Vec3> = ridingState(Vec3.ZERO, Side.BOTH)
open val stamina: SidedRidingState<Float> = ridingState(1.0F, Side.BOTH)
open fun reset() {
rideVelocity.set(Vec3.ZERO, true)
stamina.set(1.0F, true)
}
open fun copy(): RidingBehaviourState {
val copy = RidingBehaviourState()
copy.rideVelocity.set(rideVelocity.get(), true)
copy.stamina.set(stamina.get(), true)
return copy
}
open fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous.rideVelocity.get() != rideVelocity.get()) return true
if (previous.stamina.get() != stamina.get()) return true
return false
}
open fun encode(buffer: FriendlyByteBuf) {
buffer.writeVec3(rideVelocity.get())
buffer.writeFloat(stamina.get())
}
open fun decode(buffer: FriendlyByteBuf) {
rideVelocity.set(buffer.readVec3(), true)
stamina.set(buffer.readFloat(), true)
}
object NoState : RidingBehaviourState {
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun copy() = NoState
override fun reset() = Unit
override fun shouldSync(previous: RidingBehaviourState) = false
}
fun <T> ridingState(value: T, side: Side) = SidedRidingState(value, side)
@@ -9,32 +9,32 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeBehaviour
import net.minecraft.resources.ResourceLocation
object RidingBehaviours {
val behaviours = mutableMapOf<ResourceLocation, RidingBehaviour<*, *>>()
val behaviours = mutableMapOf<ResourceLocation, RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>>()
init {
register(BirdAirBehaviour.KEY, BirdAirBehaviour())
register(DolphinBehaviour.KEY, DolphinBehaviour())
register(FallToGlideCompositeBehaviour.KEY, FallToGlideCompositeBehaviour())
register(GenericLandBehaviour.KEY, GenericLandBehaviour())
register(GenericSwimBehaviour.KEY, GenericSwimBehaviour())
register(GliderAirBehaviour.KEY, GliderAirBehaviour())
register(HelicopterBehaviour.KEY, HelicopterBehaviour())
register(JetAirBehaviour.KEY, JetAirBehaviour())
register(JumpToFlightCompositeBehaviour.KEY, JumpToFlightCompositeBehaviour())
register(RunToJetCompositeBehaviour.KEY, RunToJetCompositeBehaviour())
register(SwimDashBehaviour.KEY, SwimDashBehaviour())
register(VehicleLandBehaviour.KEY, VehicleLandBehaviour())
register(HoverBehaviour.KEY, HoverBehaviour())
register(CompositeBehaviour.KEY, CompositeBehaviour())
}
fun register(key: ResourceLocation, behaviour: RidingBehaviour<*, *>) {
fun register(key: ResourceLocation, behaviour: RidingBehaviour<out RidingBehaviourSettings, out RidingBehaviourState>) {
if (behaviours.contains(key)) error("Behaviour already registered to key $key")
behaviours[key] = RidingController(behaviour)
behaviours[key] = RidingController(behaviour) as RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>
}
fun get(key: ResourceLocation): RidingBehaviour<*, *> {
fun get(key: ResourceLocation): RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState> {
if (!behaviours.contains(key)) error("Behaviour not registered to key $key")
return behaviours[key]!!
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -24,6 +25,7 @@ import net.minecraft.world.phys.Vec3
class RidingController<Settings : RidingBehaviourSettings, State : RidingBehaviourState>(val behaviour: RidingBehaviour<Settings, State>) : RidingBehaviour<Settings, State> {
override val key = behaviour.key
override val style = behaviour.style
override fun isActive(settings: Settings, state: State, vehicle: PokemonEntity) =
behaviour.isActive(settings, state, vehicle)
@@ -39,8 +41,13 @@ class RidingController<Settings : RidingBehaviourSettings, State : RidingBehavio
return behaviour.speed(settings, state, vehicle, driver)
}
override fun clampPassengerRotation(settings: Settings, state: State, vehicle: PokemonEntity, driver: LivingEntity) {
if (!isActive(settings, state, vehicle)) return
return behaviour.clampPassengerRotation(settings, state, vehicle, driver)
}
override fun rotation(settings: Settings, state: State, vehicle: PokemonEntity, driver: LivingEntity): Vec2 {
if (!isActive(settings, state, vehicle)) return vehicle.rotationVector
if (!isActive(settings, state, vehicle)) return driver.rotationVector
return behaviour.rotation(settings, state, vehicle, driver)
}
@@ -164,8 +171,8 @@ class RidingController<Settings : RidingBehaviourSettings, State : RidingBehavio
return behaviour.setRideBar(settings, state, vehicle, driver)
}
override fun createDefaultState(): State {
return behaviour.createDefaultState()
override fun createDefaultState(settings: Settings): State {
return behaviour.createDefaultState(settings)
}
}
@@ -12,12 +12,14 @@ import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -25,6 +27,9 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.*
class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
@@ -33,9 +38,10 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
override val key: ResourceLocation = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<BirdAirSettings, BirdAirState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVel.get().z > 0.2 })
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.2 })
override fun isActive(settings: BirdAirSettings, state: BirdAirState, vehicle: PokemonEntity): Boolean {
return true
@@ -51,7 +57,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVel.get().length().toFloat()
return state.rideVelocity.get().length().toFloat()
}
override fun rotation(
@@ -83,11 +89,11 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
if (controller != null) {
//Need to deadzone this when straight up or down
upForce += -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
forwardForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
upForce += -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
forwardForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
upForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().y
forwardForce += sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().y
upForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().y
forwardForce += sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().y
}
@@ -104,7 +110,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
upForce = if (vehicle.y >= altitudeLimit && upForce > 0) 0.0 else upForce
}
val velocity = Vec3(state.rideVel.get().x , upForce, forwardForce)
val velocity = Vec3(state.rideVelocity.get().x , upForce, forwardForce)
return velocity
}
@@ -120,12 +126,12 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
var glideSpeedChange = 0.0
val currSpeed = state.rideVel.get().length()
val currSpeed = state.rideVelocity.get().length()
//Flag for determining if player is actively inputting
var activeInput = false
var newVelocity = Vec3(state.rideVel.get().x, state.rideVel.get().y, state.rideVel.get().z)
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
//speed up and slow down based on input
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
@@ -176,26 +182,26 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
//Lateral movement based on driver input.
val latTopSpeed = topSpeed / 2.0
if (driver.xxa != 0.0f && state.stamina.get() > 0.0) {
newVelocity = Vec3(
(newVelocity.x + (accel * driver.xxa)).coerceIn(-latTopSpeed, latTopSpeed),
newVelocity.y,
newVelocity.z)
activeInput = true
}
else {
newVelocity = Vec3(
lerp(newVelocity.x, 0.0, latTopSpeed / 20.0),
newVelocity.y,
newVelocity.z)
}
// val latTopSpeed = topSpeed / 2.0
// if (driver.xxa != 0.0f && state.stamina.get() > 0.0) {
// newVelocity = Vec3(
// (newVelocity.x + (accel * driver.xxa)).coerceIn(-latTopSpeed, latTopSpeed),
// newVelocity.y,
// newVelocity.z)
// activeInput = true
// }
// else {
// newVelocity = Vec3(
// lerp(newVelocity.x, 0.0, latTopSpeed / 20.0),
// newVelocity.y,
// newVelocity.z)
// }
//Vertical movement based on driver input.
val vertTopSpeed = topSpeed / 2.0
val vertInput = when {
driver.jumping -> 1.0
driver.isShiftKeyDown -> -1.0
driver.jumping && state.rideVelocity.get().length() < 0.3 -> 1.0
driver.isShiftKeyDown && state.rideVelocity.get().length() < 0.3 -> -1.0
else -> 0.0
}
@@ -222,25 +228,26 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
}
//Only perform stamina logic if the ride does not have infinite stamina
if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
if (activeInput) {
state.stamina.set(state.stamina.get() - (0.05 / staminaStat).toFloat())
}
//Lose a base amount of stamina just for being airborne
state.stamina.set(state.stamina.get() - (0.01 / staminaStat).toFloat())
}
else
{
state.stamina.set(1.0f)
}
//TODO: Reintroduce stamina drain once stats start to be polished and tweaked
// //Only perform stamina logic if the ride does not have infinite stamina
// if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
// if (activeInput) {
// state.stamina.set(state.stamina.get() - (0.05 / staminaStat).toFloat())
// }
//
// //Lose a base amount of stamina just for being airborne
// state.stamina.set(state.stamina.get() - (0.01 / staminaStat).toFloat())
// }
// else
// {
// state.stamina.set(1.0f)
// }
//air resistance
if( abs(newVelocity.z) > 0) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.003 * newVelocity.z.sign, newVelocity.z))
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.0015 * newVelocity.z.sign, newVelocity.z))
}
state.rideVel.set(newVelocity)
state.rideVelocity.set(newVelocity)
}
override fun angRollVel(
@@ -253,10 +260,17 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
if (driver !is OrientationControllable) return Vec3.ZERO
val controller = (driver as OrientationControllable).orientationController
//TODO: Tie into handling
//limit rolling based on handling and current speed.
//modulated by speed so that when flapping idle in air you are ont wobbling around to look around
//TODO: Tie handling into yaw rate
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val rotationChangeRate = 10.0
//This rotation limit will be used to know if the ride has exceeded it and its needs correcting.
val rotMin = 15.0
val rotLimit = max(handling * sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)), rotMin)
val rotationChangeRate = 100.0
var yawForce = rotationChangeRate * sin(Math.toRadians(controller.roll.toDouble()))
//for a bit of correction on the rolls limit it to a quarter the amount
@@ -266,7 +280,28 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
yawForce *= abs(cos(Math.toRadians(controller.pitch.toDouble())))
pitchForce *= abs(cos(Math.toRadians(controller.pitch.toDouble()))) * 1.5
return Vec3(yawForce, pitchForce, 0.0)
var yawDeltaDeg = deltaTime * rotationChangeRate * sin(Math.toRadians(controller.roll.toDouble())) //sin(Math.toRadians(controller.roll.toDouble())) * abs(cos(Math.toRadians(controller.pitch.toDouble())))
val trueYawDelt = yawDeltaDeg * abs(cos(Math.toRadians(controller.pitch.toDouble())))
//val pitchedYawDelt = yawDeltaDeg - trueYawDelt
controller.applyGlobalYaw(trueYawDelt.toFloat())
val correctionRate = 5.0
//Calculate correcting roll force.
if(abs(controller.roll) > rotLimit) {
state.currRollCorrectionForce.set(
state.currRollCorrectionForce.get() + ((abs(controller.roll) - rotLimit) / 180 - rotLimit) * controller.roll.sign * correctionRate * deltaTime * 0.01
)
} else {
state.currRollCorrectionForce.set(
//reduce rollCorrection gradually and make sure to
//state.currRollCorrectionForce.get() - max(correctionRate * deltaTime * 0.04, abs(state.currRollCorrectionForce.get())) * state.currRollCorrectionForce.get().sign
lerp(state.currRollCorrectionForce.get(), 0.0, deltaTime * 0.98)
)
}
//yaw, pitch, roll
return Vec3(0.0, 0.0, state.currRollCorrectionForce.get())
}
override fun rotationOnMouseXY(
@@ -300,13 +335,14 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
//modulated by speed so that when flapping idle in air you are ont wobbling around to look around
val rotMin = 15.0
var rollForce = xInput
val rotLimit = max(handling * normalizeVal(state.rideVel.get().length(), 0.0, topSpeed).pow(3), rotMin)
val rotLimit = max(handling * sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)), rotMin)
//Limit roll by non linearly decreasing inputs towards
// a rotation limit based on the current distance from
// that rotation limit
if (abs(controller.roll + rollForce) < rotLimit) {
if (sign(rollForce) == sign(controller.roll).toDouble()) {
//Grab how far the current roll is away from the roll limit
val d = abs(abs(controller.roll) - rotLimit)
rollForce *= (d.pow(2)) / (rotLimit.pow(2))
}
@@ -315,10 +351,18 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
//Give the ability to yaw with x mouse input when at low speeds.
val yawForce = xInput * ( 1.0 - normalizeVal(state.rideVel.get().length(), 0.0, topSpeed).pow(3))
val yawForce = xInput * ( 1.0 - sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)))
//Yaw locally a bit when up or down so that its more intuitive to make it out of a dive or a straight vertical
//climb
val yawForcePitched = xInput * sin(Math.toRadians(abs(controller.pitch.toDouble()))) * 0.25
//Apply yaw globally as we don't want roll or pitch changes due to local yaw when looking up or down.
controller.applyGlobalYaw(yawForce.toFloat())
//yaw, pitch, roll
return Vec3(yawForce, yInput, rollForce)
return Vec3(yawForcePitched, yInput, rollForce)
}
/*
@@ -378,7 +422,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
val glideTopSpeed = vehicle.runtime.resolveDouble(settings.glidespeedExpr)
//Must I ensure that topspeed is greater than minimum?
val normalizedGlideSpeed = normalizeVal(state.rideVel.get().length(), topSpeed, glideTopSpeed)
val normalizedGlideSpeed = normalizeVal(state.rideVelocity.get().length(), topSpeed, glideTopSpeed)
//Only ever want the fov change to be a max of 0.2 and for it to have non linear scaling.
return 1.0f + normalizedGlideSpeed.pow(2).toFloat() * 0.2f
@@ -433,7 +477,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
return false
}
override fun createDefaultState() = BirdAirState()
override fun createDefaultState(settings: BirdAirSettings) = BirdAirState()
}
@@ -457,6 +501,7 @@ class BirdAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(infiniteAltitude)
buffer.writeExpression(infiniteStamina)
buffer.writeExpression(glidespeedExpr)
@@ -479,47 +524,44 @@ class BirdAirSettings : RidingBehaviourSettings {
}
}
class BirdAirState : RidingBehaviourState {
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
class BirdAirState : RidingBehaviourState() {
var gliding = ridingState(false, Side.CLIENT)
var lastGlide = ridingState(-100L, Side.CLIENT)
var currRollCorrectionForce = ridingState(0.0, Side.CLIENT)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeVec3(rideVel.get())
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeFloat(stamina.get())
buffer.writeBoolean(gliding.get())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
rideVel.set(buffer.readVec3(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
gliding.set(buffer.readBoolean(), forced = true)
}
override fun reset() {
rideVel.set(Vec3.ZERO, forced = true)
stamina.set(1.0f, forced = true)
super.reset()
gliding.set(false, forced = true)
lastGlide.set(-100L, forced = true)
currRollCorrectionForce.set(0.0, forced = true)
}
override fun toString(): String {
return "BirdAirState(rideVel=${rideVel.get()}, stamina=${stamina.get()}, gliding=${gliding.get()})"
return "BirdAirState(rideVelocity=${rideVelocity.get()}, stamina=${stamina.get()}, gliding=${gliding.get()})"
}
override fun copy() = BirdAirState().also {
it.rideVel.set(this.rideVel.get(), forced = true)
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
it.gliding.set(this.gliding.get(), forced = true)
it.lastGlide.set(this.lastGlide.get(), forced = true)
it.currRollCorrectionForce.set(this.currRollCorrectionForce.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is BirdAirState) return false
if (previous.rideVel != rideVel) return true
if (previous.stamina != stamina) return true
if (previous.gliding != gliding) return true
return false
if (previous.gliding.get() != gliding.get()) return true
return super.shouldSync(previous)
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -18,7 +19,6 @@ import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
@@ -35,6 +35,7 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<DolphinSettings, DolphinState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
@@ -256,7 +257,7 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
return false
}
override fun createDefaultState() = DolphinState()
override fun createDefaultState(settings: DolphinSettings) = DolphinState()
}
@@ -282,6 +283,7 @@ class DolphinSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -306,13 +308,11 @@ class DolphinSettings : RidingBehaviourSettings {
}
}
class DolphinState : RidingBehaviourState {
class DolphinState : RidingBehaviourState() {
var lastVelocity = ridingState(Vec3.ZERO, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun reset() {
super.reset()
lastVelocity.set(Vec3.ZERO, forced = true)
}
@@ -321,8 +321,8 @@ class DolphinState : RidingBehaviourState {
}
override fun copy() = DolphinState().also {
it.stamina.set(stamina.get(), forced = true)
it.rideVelocity.set(rideVelocity.get(), forced = true)
it.lastVelocity.set(lastVelocity.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState) = false
}
@@ -1,434 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class FallToGlideCompositeBehaviour : RidingBehaviour<FallToGlideCompositeSettings, FallToGlideCompositeState> {
companion object {
val KEY = cobblemonResource("composite/fall_to_glide")
}
override val key = KEY
val landBehaviour: GenericLandBehaviour = GenericLandBehaviour()
val glideBehaviour: GliderAirBehaviour = GliderAirBehaviour()
override fun tick(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val shouldBeFlying = checkShouldBeFlying(settings, vehicle, state.activeController.get() == GliderAirBehaviour.KEY)
if (state.activeController.get() == GliderAirBehaviour.KEY && !shouldBeFlying) { // && entity.onGround() && state.timeTransitioned + 20 < entity.level().gameTime) {
state.activeController.set(GenericLandBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
} else if (state.activeController.get() == GenericLandBehaviour.KEY && shouldBeFlying) {
state.activeController.set(GliderAirBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
}
}
private fun checkShouldBeFlying(
settings: FallToGlideCompositeSettings,
vehicle: PokemonEntity,
isFlyingAlready: Boolean
): Boolean {
val runtime = vehicle.runtime
val minFallingSpeed = runtime.resolveFloat(settings.minimumFallSpeed)
val minForwardSpeed = runtime.resolveFloat(settings.minimumForwardSpeed)
val grounded = vehicle.onGround()
return if (isFlyingAlready) {
!grounded
} else {
vehicle.deltaMovement.y <= -minFallingSpeed && vehicle.deltaMovement.horizontalDistance() >= minForwardSpeed
}
}
override fun isActive(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun pose(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): PoseType {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.pose(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.pose(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun speed(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.speed(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.speed(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotation(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotation(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.rotation(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun velocity(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.velocity(settings.land, state.landState, vehicle, driver, input)
GliderAirBehaviour.KEY -> glideBehaviour.velocity(settings.glide, NoState, vehicle, driver, input)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun angRollVel(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.angRollVel(
settings.land,
state.landState,
vehicle,
driver,
deltaTime
)
GliderAirBehaviour.KEY -> glideBehaviour.angRollVel(settings.glide, NoState, vehicle, driver, deltaTime)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotationOnMouseXY(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotationOnMouseXY(
settings.land,
state.landState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
GliderAirBehaviour.KEY -> glideBehaviour.rotationOnMouseXY(
settings.glide,
NoState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun canJump(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.canJump(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.canJump(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun setRideBar(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.setRideBar(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.setRideBar(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun jumpForce(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.jumpForce(
settings.land,
state.landState,
vehicle,
driver,
jumpStrength
)
GliderAirBehaviour.KEY -> glideBehaviour.jumpForce(settings.glide, NoState, vehicle, driver, jumpStrength)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun gravity(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.gravity(settings.land, state.landState, vehicle, regularGravity)
GliderAirBehaviour.KEY -> glideBehaviour.gravity(settings.glide, NoState, vehicle, regularGravity)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rideFovMultiplier(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rideFovMultiplier(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.rideFovMultiplier(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useAngVelSmoothing(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useAngVelSmoothing(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.useAngVelSmoothing(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useRidingAltPose(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useRidingAltPose(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.useRidingAltPose(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun inertia(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.inertia(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.inertia(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRoll(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRoll(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.shouldRoll(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun turnOffOnGround(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.turnOffOnGround(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.turnOffOnGround(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun dismountOnShift(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.dismountOnShift(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.dismountOnShift(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePokemonHead(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePokemonHead(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.shouldRotatePokemonHead(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePlayerHead(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePlayerHead(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.shouldRotatePlayerHead(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun createDefaultState() = FallToGlideCompositeState()
}
class FallToGlideCompositeSettings : RidingBehaviourSettings {
override val key = FallToGlideCompositeBehaviour.KEY
var glide: GliderAirSettings = GliderAirSettings()
private set
var land: GenericLandSettings = GenericLandSettings()
private set
var minimumForwardSpeed: Expression = "0.0".asExpression()
private set
var minimumFallSpeed: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
glide.encode(buffer)
land.encode(buffer)
buffer.writeExpression(minimumForwardSpeed)
buffer.writeExpression(minimumFallSpeed)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
glide.decode(buffer)
land.decode(buffer)
minimumForwardSpeed = buffer.readExpression()
minimumFallSpeed = buffer.readExpression()
}
}
class FallToGlideCompositeState : RidingBehaviourState {
var activeController = ridingState(GenericLandBehaviour.KEY, Side.CLIENT)
var landState: GenericLandState = GenericLandState()
var timeTransitioned = ridingState(-100L, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(activeController.get())
landState.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
activeController.set(buffer.readResourceLocation(), forced = true)
landState.decode(buffer)
}
override fun reset() {
activeController.set(GenericLandBehaviour.KEY, forced = true)
landState.reset()
timeTransitioned.set(-100L, forced = true)
}
override fun toString(): String {
return "FallToGlideCompositeState(activeController=$activeController, landState=$landState, timeTransitioned=$timeTransitioned)"
}
override fun copy() = FallToGlideCompositeState().also {
it.activeController.set(activeController.get(), forced = true)
it.landState = landState.copy()
it.timeTransitioned.set(timeTransitioned.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is FallToGlideCompositeState) return false
if (activeController != previous.activeController) return true
if (landState.shouldSync(previous.landState)) return true
return false
}
}
@@ -9,7 +9,8 @@
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -17,15 +18,14 @@ import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.util.Mth
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.*
class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandState> {
companion object {
@@ -33,10 +33,11 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
}
override val key = KEY
override val style = RidingStyle.LAND
val poseProvider = PoseProvider<GenericLandSettings, GenericLandState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, state, _ ->
return@PoseOption state.rideVel.get().z > 0.1
return@PoseOption abs(state.rideVelocity.get().z) > 0.2
})
override fun isActive(
@@ -72,18 +73,102 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVel.get().length().toFloat()
return state.rideVelocity.get().length().toFloat()
}
override fun updatePassengerRotation(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
//Take the inverse so that it cancels out how
//much the entity rotates.
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotMod = Mth.wrapDegrees(driver.yRot - vehicle.yRot) / maxYawDiff
val rotAmount = 10.0f
//Take the inverse so that you turn more at higher speeds
val normSpeed = 1.0f - 0.5f*normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed).toFloat()
//driver.yRot += (entity.riding.deltaRotation.y - turnAmount)
//driver.setYHeadRot(driver.yHeadRot + (entity.riding.deltaRotation.y) - turnAmount)
}
override fun clampPassengerRotation(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
val f = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val lookYawLimit = 90.0f
val g = Mth.clamp(f, -lookYawLimit, lookYawLimit)
driver.yRotO += g - f
driver.yRot = driver.yRot + g - f
driver.setYHeadRot(driver.yRot)
}
override fun rotation(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return Vec2(driver.xRot * 0.5f, driver.yRot)
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
return Vec2(vehicle.xRot, vehicle.yRot + turnAmount )
}
/*
* Calculates the rotation amount given the difference between
* the current player y rot and entity y rot. This gives the
* affect of influencing a rides rotation through the mouse
* without it being instant.
*/
fun calcRotAmount(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
//In degrees per second
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val rotDiffNorm = rotDiff / maxYawDiff
//Take the square root so that the ride levels out quicker when at lower differences between entity
//y and driver y
//This influences the speed of the turn based on how far in one direction you're looking
val rotDiffMod = (sqrt(abs(rotDiffNorm)) * rotDiffNorm.sign)
//Take the inverse so that you turn less at higher speeds
val normSpeed = 1.0f // = 1.0f - 0.5f*normalizeVal(state.rideVelocityocity.length(), 0.0, topSpeed).toFloat()
// TODO: This needs to be tweaked with in game results and testing
val turnRate = (handling.toFloat() / 20.0f) * 2
//Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod * normSpeed
val rotAmount = turnSpeed.coerceIn(-abs(rotDiff), abs(rotDiff))
return rotAmount
}
override fun velocity(
settings: GenericLandSettings,
state: GenericLandState,
@@ -91,24 +176,16 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player,
input: Vec3
): Vec3 {
val runtime = vehicle.runtime
val driveFactor = runtime.resolveFloat(settings.driveFactor)
val strafeFactor = runtime.resolveFloat(settings.strafeFactor)
val f = driver.xxa * strafeFactor
var g = driver.zza * driveFactor
if (g <= 0.0f) {
g *= runtime.resolveFloat(settings.reverseDriveFactor)
}
val gravity = -1.0
//Limit horizontal velocity that may have accumulated through alternate behaviour
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val currVel = state.rideVelocity.get()
// state.rideVelocity.set(Vec3(
// max(currVel.x, topSpeed),
// currVel.y,
// max(currVel.z, topSpeed)
// ))
val newVelocity = calculateRideSpaceVel(settings, state, vehicle, driver)
//Jump the thang!
if (driver.jumping && vehicle.onGround()) {
state.rideVel.set(Vec3(newVelocity.x, 2.0, newVelocity.z))
} else {
state.rideVel.set(newVelocity)
}
state.rideVelocity.set(calculateRideSpaceVel(settings, state, vehicle, driver))
//This is cheap.
//Also make it stop quicker the slower it is.
@@ -118,7 +195,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
//entity.deltaMovement = entity.deltaMovement.lerp(velocity, 1.0)
//state.currVel = state.currVel.add( f.toDouble() / 20.0, gravity / 20.0 , g.toDouble() / 20.0)
return state.rideVel.get()
return state.rideVelocity.get()
}
private fun calculateRideSpaceVel(
@@ -127,35 +204,59 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val topSpeed = vehicle.runtime.resolveDouble(settings.topSpeedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelExpr)
val speed = state.rideVel.get().length()
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val speed = state.rideVelocity.get().length()
val minSpeed = 0.0
//Flag for determining if player is actively inputting
var activeInput = false
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
var newVelocity = Vec3(state.rideVel.get().x, state.rideVel.get().y, state.rideVel.get().z)
//speed up and slow down based on input
if (driver.zza > 0.0 && speed <= topSpeed && state.stamina.get() > 0.0f) {
//modify acceleration to be slower when at closer speeds to top speed
val accelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2), 0.1)
newVelocity = Vec3(newVelocity.x, newVelocity.y, min(newVelocity.z + (accel * accelMod), topSpeed))
} else if (driver.zza >= 0.0 && state.stamina.get() == 0.0f || speed > topSpeed) {
newVelocity = Vec3(newVelocity.x, newVelocity.y, max(newVelocity.z - ((accel) / 4), minSpeed))
} else if (driver.zza < 0.0 && speed > minSpeed) {
//modify deccel to be slower when at closer speeds to minimum speed
val deccelMod = max(-(normalizeSpeed(speed, minSpeed, topSpeed)) + 1, 0.0)
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
//make sure it can't exceed top speed
val forwardInput = when {
driver.zza > 0 && newVelocity.z > topSpeed -> 0.0
driver.zza < 0 && newVelocity.z < (-topSpeed / 3.0) -> 0.0
else -> driver.zza.sign
}
//Decelerate currently always a constant half of max acceleration.
newVelocity =
Vec3(newVelocity.x, newVelocity.y, max(newVelocity.z - ((accel * deccelMod) / 2), minSpeed))
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
}
//Gravity logic
if (vehicle.onGround()) {
newVelocity = Vec3(newVelocity.x, 0.0, newVelocity.z)
} else {
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - 0.2, -1.0), newVelocity.z)
val gravity = (9.8 / ( 20.0)) * 0.2
val terminalVel = 2.0
val fallingForce = gravity - ( newVelocity.z.sign *gravity *(abs(newVelocity.z) / 2.0))
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - fallingForce, -terminalVel), newVelocity.z)
}
//ground Friction
if( abs(newVelocity.z) > 0 && vehicle.onGround() && !activeInput) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.03 * newVelocity.z.sign, newVelocity.z))
}
//Jump the thang!
if (driver.jumping && vehicle.onGround()) {
val jumpVel = 1.0
newVelocity = newVelocity.add(0.0, 1.0, 0.0)
//Ensure this doesn't add unwanted forward velocity
val mag = if(newVelocity.length() < topSpeed) newVelocity.length() else topSpeed
newVelocity = newVelocity.normalize().scale(mag)
}
return newVelocity
}
@@ -163,7 +264,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
* Normalizes the current speed between minSpeed and maxSpeed.
* The result is clamped between 0.0 and 1.0, where 0.0 represents minSpeed and 1.0 represents maxSpeed.
*/
private fun normalizeSpeed(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
private fun normalizeVal(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
require(maxSpeed > minSpeed) { "maxSpeed must be greater than minSpeed" }
return ((currSpeed - minSpeed) / (maxSpeed - minSpeed)).coerceIn(0.0, 1.0)
}
@@ -215,8 +316,6 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player
): Float {
//Retrieve stamina from state and tick up at a rate of 0.1 a second
val staminaGain = (1.0 / 20.0) * 0.1
state.stamina.set(min(state.stamina.get() + staminaGain, 1.0).toFloat())
return (state.stamina.get() / 1.0f)
}
@@ -227,10 +326,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player,
jumpStrength: Int
): Vec3 {
val runtime = vehicle.runtime
runtime.environment.query.addFunction("jump_strength") { DoubleValue(jumpStrength.toDouble()) }
val jumpVector = settings.jumpVector.map { runtime.resolveFloat(it) }
return Vec3(jumpVector[0].toDouble(), jumpVector[1].toDouble(), jumpVector[2].toDouble())
return Vec3.ZERO
}
override fun gravity(
@@ -316,30 +412,21 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
return false
}
override fun createDefaultState() = GenericLandState()
override fun createDefaultState(settings: GenericLandSettings) = GenericLandState()
}
class GenericLandSettings : RidingBehaviourSettings {
override val key = GenericLandBehaviour.KEY
var driveFactor = "1.0".asExpression()
var canJump = "true".asExpression()
private set
var strafeFactor = "0.2".asExpression()
private set
var reverseDriveFactor = "0.25".asExpression()
private set
var topSpeedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.3)".asExpression()
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.3)".asExpression()
private set
// Max accel is a whole 1.0 in 1 second. The conversion in the function below is to convert seconds to ticks
var accelExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 0.5)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
var jumpVector = listOf("0".asExpression(), "0.3".asExpression(), "0".asExpression())
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 1.5)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
@@ -354,30 +441,17 @@ class GenericLandSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeExpression(driveFactor)
buffer.writeExpression(strafeFactor)
buffer.writeExpression(reverseDriveFactor)
buffer.writeExpression(topSpeedExpr)
buffer.writeExpression(accelExpr)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
buffer.writeExpression(jumpVector[2])
buffer.writeResourceLocation(key)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
driveFactor = buffer.readExpression()
strafeFactor = buffer.readExpression()
reverseDriveFactor = buffer.readExpression()
topSpeedExpr = buffer.readExpression()
accelExpr = buffer.readExpression()
jumpVector = listOf(
buffer.readExpression(),
buffer.readExpression(),
buffer.readExpression()
)
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
@@ -385,41 +459,16 @@ class GenericLandSettings : RidingBehaviourSettings {
}
class GenericLandState : RidingBehaviourState {
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
class GenericLandState : RidingBehaviourState() {
var currSpeed = ridingState(0.0, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeVec3(rideVel.get())
buffer.writeFloat(stamina.get())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
rideVel.set(buffer.readVec3(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
}
override fun reset() {
rideVel.set(Vec3.ZERO, forced = true)
stamina.set(1.0f, forced = true)
currSpeed.set(0.0, forced = true)
}
override fun toString(): String {
return "GenericLandState(rideVel=${rideVel.get()}, stamina=${stamina.get()}, currSpeed=${currSpeed.get()})"
}
override fun copy() = GenericLandState().also {
it.rideVel.set(this.rideVel.get(), forced = true)
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
it.currSpeed.set(this.currSpeed.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is GenericLandState) return false
if (rideVel != previous.rideVel) return true
if (stamina != previous.stamina) return true
return false
return super.shouldSync(previous)
}
}
@@ -11,7 +11,8 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.behaviour.NoState
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -28,17 +29,18 @@ import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviourState> {
companion object {
val KEY = cobblemonResource("swim/generic")
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<GenericSwimSettings, NoState>(PoseType.FLOAT)
val poseProvider = PoseProvider<GenericSwimSettings, RidingBehaviourState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.isSwimming && entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any true
@@ -48,17 +50,17 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
}
}
override fun pose(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
}
override fun rotation(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -67,7 +69,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun velocity(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -88,7 +90,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun angRollVel(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -98,7 +100,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun rotationOnMouseXY(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -118,7 +120,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun canJump(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
@@ -127,7 +129,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun setRideBar(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -136,7 +138,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun jumpForce(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -149,7 +151,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun gravity(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -158,45 +160,45 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun rideFovMultiplier(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun useRidingAltPose(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Double {
override fun inertia(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
return 0.5
}
override fun shouldRoll(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun turnOffOnGround(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity
): Boolean {
return false
@@ -204,13 +206,13 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun shouldRotatePlayerHead(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun createDefaultState() = NoState
override fun createDefaultState(settings: GenericSwimSettings) = RidingBehaviourState()
}
@@ -236,6 +238,7 @@ class GenericSwimSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -12,7 +12,7 @@ import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.NoState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -29,31 +29,32 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourState> {
companion object {
val KEY = cobblemonResource("air/glider")
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<GliderAirSettings, NoState>(PoseType.HOVER)
val poseProvider = PoseProvider<GliderAirSettings, RidingBehaviourState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return true
}
override fun pose(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
}
override fun rotation(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -62,7 +63,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun velocity(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -77,7 +78,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun angRollVel(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -87,7 +88,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun rotationOnMouseXY(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -105,13 +106,13 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
return Vec3(0.0, mouseY * invertPitch, mouseX * invertRoll)
}
override fun canJump(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Boolean {
override fun canJump(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Boolean {
return false
}
override fun setRideBar(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -120,7 +121,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun jumpForce(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -130,7 +131,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun gravity(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -139,51 +140,51 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun rideFovMultiplier(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun useRidingAltPose(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Double {
override fun inertia(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
return 0.5
}
override fun shouldRoll(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun turnOffOnGround(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePokemonHead(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePlayerHead(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePlayerHead(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun createDefaultState() = NoState
override fun createDefaultState(settings: GliderAirSettings) = RidingBehaviourState()
}
class GliderAirSettings : RidingBehaviourSettings {
@@ -199,6 +200,7 @@ class GliderAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(glideSpeed)
buffer.writeExpression(speed)
buffer.writeExpression(canStrafe)
@@ -11,7 +11,8 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.behaviour.NoState
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -31,18 +32,19 @@ import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sin
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourState> {
companion object {
val KEY = cobblemonResource("air/helicopter")
val ROTATION_LIMIT = 30.0f
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<HelicopterSettings, NoState>(PoseType.HOVER)
val poseProvider = PoseProvider<HelicopterSettings, RidingBehaviourState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
//If there are only fluid blocks or air block below the ride
//then activate the controller. If it is in water the ride will
//dismount accordingly
@@ -56,11 +58,11 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
}
}
override fun pose(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
//Increased max speed to exaggerate movement.
//This likely just needs to be a static number if it really is just
//the scalar for the velocity vector
@@ -69,7 +71,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun rotation(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -78,7 +80,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun velocity(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -107,7 +109,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun angRollVel(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -162,7 +164,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun rotationOnMouseXY(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -182,7 +184,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun canJump(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
@@ -191,7 +193,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun setRideBar(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -200,7 +202,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun jumpForce(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -210,7 +212,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun gravity(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -219,55 +221,55 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun rideFovMultiplier(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return true
}
override fun useRidingAltPose(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Double {
override fun inertia(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
return 0.1
}
override fun shouldRoll(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return true
}
override fun turnOffOnGround(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePlayerHead(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePlayerHead(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun createDefaultState() = NoState
override fun createDefaultState(settings: HelicopterSettings) = RidingBehaviourState()
}
@@ -287,6 +289,7 @@ class HelicopterSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(gravity)
buffer.writeExpression(horizontalAcceleration)
buffer.writeExpression(verticalVelocity)
@@ -0,0 +1,479 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.util.Mth
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.*
class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
companion object {
val KEY = cobblemonResource("air/hover")
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<HoverSettings, HoverState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, state, _ ->
return@PoseOption abs(state.rideVelocity.get().z) > 0.2
})
override fun isActive(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
//Need to check other fluids
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any false
}
//This might not actually work, depending on what the yPos actually is. yPos of the middle of the entity? the feet?
if (it.y.toDouble() == (vehicle.position().y)) {
val blockState = vehicle.level().getBlockState(it.below())
return@any !blockState.isAir && blockState.fluidState.isEmpty
}
true
}
}
override fun pose(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): PoseType {
return this.poseProvider.select(settings, state, vehicle)
}
override fun speed(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVelocity.get().length().toFloat()
}
override fun updatePassengerRotation(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
//Take the inverse so that it cancels out how
//much the entity rotates.
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotMod = Mth.wrapDegrees(driver.yRot - vehicle.yRot) / maxYawDiff
val rotAmount = 10.0f
//Take the inverse so that you turn more at higher speeds
val normSpeed = 1.0f - 0.5f*normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed).toFloat()
//driver.yRot += (entity.riding.deltaRotation.y - turnAmount)
//driver.setYHeadRot(driver.yHeadRot + (entity.riding.deltaRotation.y) - turnAmount)
}
override fun clampPassengerRotation(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
val f = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val lookYawLimit = 90.0f
val g = Mth.clamp(f, -lookYawLimit, lookYawLimit)
driver.yRotO += g - f
driver.yRot = driver.yRot + g - f
driver.setYHeadRot(driver.yRot)
}
override fun rotation(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
return Vec2(driver.xRot, vehicle.yRot + turnAmount )
}
/*
* Calculates the rotation amount given the difference between
* the current player y rot and entity y rot. This gives the
* affect of influencing a rides rotation through the mouse
* without it being instant.
*/
fun calcRotAmount(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
//In degrees per second
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val rotDiffNorm = rotDiff / maxYawDiff
//Take the square root so that the ride levels out quicker when at lower differences between entity
//y and driver y
//This influences the speed of the turn based on how far in one direction you're looking
val rotDiffMod = (sqrt(abs(rotDiffNorm)) * rotDiffNorm.sign)
//Take the inverse so that you turn less at higher speeds
val normSpeed = 1.0f // = 1.0f - 0.5f*normalizeVal(state.rideVelocityocity.length(), 0.0, topSpeed).toFloat()
// TODO: This needs to be tweaked with in game results and testing
val turnRate = (handling.toFloat() / 20.0f) * 2
//Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod * normSpeed
val rotAmount = turnSpeed.coerceIn(-abs(rotDiff), abs(rotDiff))
return rotAmount
}
override fun velocity(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
val strafeFactor = 0.2
val f = driver.xxa * strafeFactor
var g = driver.zza
if (g <= 0.0f) {
g *= -1.0f
}
return calculateRideSpaceVel(settings, state, vehicle, driver).scale(10.0)
}
private fun calculateRideSpaceVel(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val speed = state.rideVelocity.get().length()
//Flag for determining if player is actively inputting
var activeInput = false
val minSpeed = 0.0
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
var jumpVec = Vec3.ZERO
//speed up and slow down based on input
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
//make sure it can't exceed top speed
val forwardInput = when {
driver.zza > 0 && newVelocity.z > topSpeed -> 0.0
driver.zza < 0 && newVelocity.z < (-topSpeed / 3.0) -> 0.0
else -> driver.zza.sign
}
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
jumpVec = jumpVec.add(0.0, 0.0, forwardInput.toDouble())
}
//speed up and slow down based on input
if (driver.xxa != 0.0f && state.stamina.get() > 0.0) {
//make sure it can't exceed top speed
val forwardInput = when {
driver.xxa > 0 && newVelocity.x > topSpeed -> 0.0
driver.xxa < 0 && newVelocity.x < (-topSpeed / 3.0) -> 0.0
else -> driver.xxa.sign
}
newVelocity = Vec3(
newVelocity.x + (accel * forwardInput.toDouble()),
newVelocity.y,
(newVelocity.z ))
activeInput = true
}
//Vertical movement based on driver input.
val vertTopSpeed = topSpeed / 2.0
val vertInput = when {
driver.jumping -> 1.0
driver.isShiftKeyDown -> -1.0
else -> 0.0
}
if (vertInput != 0.0 && state.stamina.get() > 0.0) {
newVelocity = Vec3(
newVelocity.x,
(newVelocity.y + (accel * vertInput)).coerceIn(-vertTopSpeed, vertTopSpeed),
newVelocity.z)
activeInput = true
}
//air Friction
return newVelocity
}
/*
* Normalizes the current speed between minSpeed and maxSpeed.
* The result is clamped between 0.0 and 1.0, where 0.0 represents minSpeed and 1.0 represents maxSpeed.
*/
private fun normalizeVal(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
require(maxSpeed > minSpeed) { "maxSpeed must be greater than minSpeed" }
return ((currSpeed - minSpeed) / (maxSpeed - minSpeed)).coerceIn(0.0, 1.0)
}
override fun angRollVel(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return Vec3.ZERO
}
override fun rotationOnMouseXY(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
//Smooth out mouse input.
val smoothingSpeed = 4
val xInput = mouseXSmoother.getNewDeltaValue(mouseX * 0.1, deltaTime * smoothingSpeed);
val yInput = mouseYSmoother.getNewDeltaValue(mouseY * 0.1, deltaTime * smoothingSpeed);
//yaw, pitch, roll
return Vec3(0.0, yInput, xInput)
}
override fun canJump(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun setRideBar(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Float {
//Retrieve stamina from state and use it to set the "stamina bar"
return (state.stamina.get() / 1.0f)
}
override fun jumpForce(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return Vec3.ZERO
}
override fun gravity(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return 0.0
}
override fun rideFovMultiplier(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun useRidingAltPose(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Double {
return 0.05
}
override fun shouldRoll(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun turnOffOnGround(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun dismountOnShift(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePlayerHead(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun createDefaultState(settings: HoverSettings) = HoverState()
}
class HoverSettings : RidingBehaviourSettings {
override val key = HoverBehaviour.KEY
var canJump = "true".asExpression()
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 1.0, 0.3)".asExpression()
private set
// Max accel is a whole 1.0 in 1 second. The conversion in the function below is to convert seconds to ticks
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'AIR', (1.0 / (20.0 * 0.5)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'AIR', 30.0, 10.0)".asExpression()
private set
//Between a one block jump and a ten block jump
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'AIR', 10.0, 1.0)".asExpression()
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 140.0, 20.0)".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
}
}
class HoverState : RidingBehaviourState() {
override fun copy() = HoverState().also {
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is HoverState) return false
return super.shouldSync(previous)
}
}
@@ -11,12 +11,14 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -24,6 +26,7 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.*
class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
@@ -32,12 +35,24 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<JetAirSettings, JetAirState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVel.get().z > 0.1 })
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.1 })
override fun isActive(settings: JetAirSettings, state: JetAirState, vehicle: PokemonEntity): Boolean {
return true
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
//Need to check other fluids
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any false
}
//This might not actually work, depending on what the yPos actually is. yPos of the middle of the entity? the feet?
if (it.y.toDouble() == (vehicle.position().y)) {
val blockState = vehicle.level().getBlockState(it.below())
return@any !(!blockState.isAir && blockState.fluidState.isEmpty)
}
true
}
}
override fun pose(settings: JetAirSettings, state: JetAirState, vehicle: PokemonEntity): PoseType {
@@ -52,24 +67,26 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
//retrieve minSpeed
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
//Reduce stamina unless stamina is infinite
if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
//Calculate stamina loss due to speed
//At max speed it will tick down 0.1 a second so the stamina will last ten seconds
//There has got to be a better way to express this equation. It interpolates between 0.5 and 1.0
var staminaRate = (normalizeSpeed(state.rideVel.get().length(), minSpeed, topSpeed))
//TODO: Reintroduce stamina drain once stats start to be polished and tweaked
state.stamina.set(1.0f)
// //Reduce stamina unless stamina is infinite
// if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
// //Calculate stamina loss due to speed
// //At max speed it will tick down 0.1 a second so the stamina will last ten seconds
// //There has got to be a better way to express this equation. It interpolates between 0.5 and 1.0
// var staminaRate = (normalizeSpeed(state.rideVelocity.get().length(), minSpeed, topSpeed))
//
// //interpolate between 0.25 and 1.0 so that you always have at least a min of 0.25 stam loss
// staminaRate = 0.25 + (0.75 * staminaRate.pow(3))
//
// //Calculate stamina loss in seconds achievable at top speed
// val staminaLoss = staminaRate * (1.0 / (20.0 * staminaStat))
// state.stamina.set(max(state.stamina.get() - staminaLoss, 0.0).toFloat())
// } else {
// state.stamina.set(1.0f)
// }
//interpolate between 0.25 and 1.0 so that you always have at least a min of 0.25 stam loss
staminaRate = 0.25 + (0.75 * staminaRate.pow(3))
//Calculate stamina loss in seconds achievable at top speed
val staminaLoss = staminaRate * (1.0 / (20.0 * staminaStat))
state.stamina.set(max(state.stamina.get() - staminaLoss, 0.0).toFloat())
} else {
state.stamina.set(1.0f)
}
return state.rideVel.get().length().toFloat()
return state.rideVelocity.get().length().toFloat()
}
//TODO: Move these functions to a riding util class.
@@ -108,8 +125,8 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
//Translate ride space velocity to world space velocity.
if (controller != null) {
upForce = -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
forwardForce = cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
upForce = -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
forwardForce = cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
}
//If stamina has run out then initiate forced glide down.
@@ -141,7 +158,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val altitudeLimit = vehicle.runtime.resolveDouble(settings.jumpExpr)
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
val speed = state.rideVel.get().length()
val speed = state.rideVelocity.get().length()
//Give no altitude limit if at max jump stat.
val pushingHeightLimit = if (vehicle.runtime.resolveBoolean(settings.infiniteStamina)) false
@@ -152,15 +169,15 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
if (driver.zza > 0.0 && speed < topSpeed && state.stamina.get() > 0.0f && !pushingHeightLimit) {
//modify acceleration to be slower when at closer speeds to top speed
val accelMod = max(-(normalizeSpeed(speed, minSpeed, topSpeed)) + 1, 0.0)
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, min(state.rideVel.get().z + (accel * accelMod), topSpeed)))
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, min(state.rideVelocity.get().z + (accel * accelMod), topSpeed)))
} else if (driver.zza >= 0.0 && (state.stamina.get() == 0.0f || pushingHeightLimit)) {
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, max(state.rideVel.get().z - ((accel) / 4), minSpeed)))
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, max(state.rideVelocity.get().z - ((accel) / 4), minSpeed)))
} else if (driver.zza < 0.0 && speed > minSpeed) {
//modify deccel to be slower when at closer speeds to minimum speed
val deccelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2), 0.1)
val deccelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2) * 8, 0.1)
//Decelerate currently always a constant half of max acceleration.
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, max(state.rideVel.get().z - ((accel * deccelMod) / 2), minSpeed)))
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, max(state.rideVelocity.get().z - ((accel * deccelMod) / 2), minSpeed)))
}
}
@@ -209,8 +226,13 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val invertRoll = if (Cobblemon.config.invertRoll) -1 else 1
val invertPitch = if (Cobblemon.config.invertPitch) -1 else 1
// Accumulate the mouse input
state.currMouseXForce.set((state.currMouseXForce.get() + (0.0015 * mouseX * invertRoll)).coerceIn(-1.0, 1.0))
// Smooth out and accumulate roll input
val smoothingSpeed = 4.0
val mouseXc = (mouseX).coerceIn(-60.0, 60.0)
val xInput = mouseXSmoother.getNewDeltaValue(mouseXc * 0.1 * invertRoll, deltaTime * smoothingSpeed);
// Accumulate the y mouse input for pitch
//state.currMouseXForce.set((state.currMouseXForce.get() + (0.0015 * mouseX * invertRoll)).coerceIn(-1.0, 1.0))
state.currMouseYForce.set((state.currMouseYForce.get() + (0.0015 * mouseY * invertPitch)).coerceIn(-1.0, 1.0))
//Get handling in degrees per second
@@ -232,8 +254,9 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val pitchRot = handling * state.currMouseYForce.get()
//Roll is 1.5 times as fast as pitch
val rollRot = handling * 1.5 * state.currMouseXForce.get()
//val rollRot = handling * 1.5 * state.currMouseXForce.get()
val rollRot = handling * 1.5 * xInput.coerceIn(-1.0,1.0)
//yaw, pitch, roll
return Vec3(0.0, pitchRot, rollRot)
}
@@ -285,7 +308,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
//Must I ensure that topspeed is greater than minimum?
val normalizedSpeed = normalizeSpeed(state.rideVel.get().length(), minSpeed, topSpeed)
val normalizedSpeed = normalizeSpeed(state.rideVelocity.get().length(), minSpeed, topSpeed)
//TODO: Determine if this should be based on max possible speed instead of top speed.
//Only ever want the fov change to be a max of 0.2 and for it to have non linear scaling.
@@ -333,7 +356,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
return false
}
override fun createDefaultState() = JetAirState()
override fun createDefaultState(settings: JetAirSettings) = JetAirState()
}
class JetAirSettings : RidingBehaviourSettings {
@@ -342,10 +365,10 @@ class JetAirSettings : RidingBehaviourSettings {
var gravity: Expression = "0".asExpression()
private set
var minSpeed: Expression = "1.2".asExpression()
var minSpeed: Expression = "0.8".asExpression()
private set
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 25.0, 8.0)".asExpression()
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 50.0, 25.0)".asExpression()
private set
// Make configurable by json
@@ -359,7 +382,7 @@ class JetAirSettings : RidingBehaviourSettings {
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 140.0, 20.0)".asExpression()
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 2.5, 1.0)".asExpression()
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 1.8, 1.0)".asExpression()
private set
var accelerationExpr: Expression = "q.get_ride_stats('ACCELERATION', 'AIR', (1.0 / (20.0 * 1.0)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
@@ -367,6 +390,7 @@ class JetAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(gravity)
buffer.writeExpression(minSpeed)
buffer.writeExpression(handlingYawExpr)
@@ -393,50 +417,40 @@ class JetAirSettings : RidingBehaviourSettings {
}
}
class JetAirState : RidingBehaviourState {
class JetAirState : RidingBehaviourState() {
var currSpeed = ridingState(0.0, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var currMouseXForce = ridingState(0.0, Side.BOTH)
var currMouseYForce = ridingState(0.0, Side.BOTH)
var currMouseXForce = ridingState(0.0, Side.CLIENT)
var currMouseYForce = ridingState(0.0, Side.CLIENT)
override fun encode(buffer: RegistryFriendlyByteBuf) {
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeDouble(currSpeed.get())
buffer.writeFloat(stamina.get())
buffer.writeVec3(rideVel.get())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
currSpeed.set(buffer.readDouble(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
rideVel.set(buffer.readVec3(), forced = true)
}
override fun reset() {
super.reset()
currSpeed.set(0.0, forced = true)
stamina.set(1.0f, forced = true)
rideVel.set(Vec3.ZERO, forced = true)
currMouseXForce.set(0.0, forced = true)
currMouseYForce.set(0.0, forced = true)
}
override fun toString(): String {
return "JetAirState(currSpeed=${currSpeed.get()}, stamina=${stamina.get()}, rideVel=${rideVel.get()}, currMouseXForce=${currMouseXForce.get()}, currMouseYForce=${currMouseYForce.get()})"
}
override fun copy() = JetAirState().also {
it.currSpeed.set(currSpeed.get(), forced = true)
it.stamina.set(stamina.get(), forced = true)
it.rideVel.set(rideVel.get(), forced = true)
it.currMouseXForce.set(currMouseXForce.get(), forced = true)
it.currMouseYForce.set(currMouseYForce.get(), forced = true)
it.rideVelocity.set(rideVelocity.get(), forced = true)
// it.currMouseXForce.set(currMouseXForce.get(), forced = true)
// it.currMouseYForce.set(currMouseYForce.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is JetAirState) return false
if (previous.currSpeed != currSpeed) return true
if (previous.stamina != stamina) return true
if (previous.rideVel != rideVel) return true
return false
return super.shouldSync(previous)
}
}
@@ -1,469 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readExpression
import com.cobblemon.mod.common.util.writeExpression
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class JumpToFlightCompositeBehaviour : RidingBehaviour<JumpToFlightCompositeSettings, JumpToFlightCompositeState> {
companion object {
val KEY = cobblemonResource("composite/jump_to_flight")
}
override val key = KEY
val landBehaviour: GenericLandBehaviour = GenericLandBehaviour()
val birdBehaviour: BirdAirBehaviour = BirdAirBehaviour()
override fun tick(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val flightState = state.flightState
val groundState = state.landState
if (shouldTransitionToGround(state, vehicle)) {
//Pass the speed to the next state
// groundState.currSpeed = flightState.currSpeed
groundState.rideVel.set(flightState.rideVel.get())
groundState.stamina.set(flightState.stamina.get())
state.activeController.set(GenericLandBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
state.timeTransitioned.set(vehicle.level().gameTime)
} else if (shouldTransitionToAir(state, vehicle, driver)) {
//Pass the speed to the next state
// flightState.currSpeed = groundState.currSpeed
flightState.rideVel.set(groundState.rideVel.get())
flightState.stamina.set(groundState.stamina.get())
state.activeController.set(BirdAirBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
state.timeTransitioned.set(vehicle.level().gameTime)
}
}
override fun isActive(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return true
}
private fun shouldTransitionToGround(state: JumpToFlightCompositeState, entity: PokemonEntity): Boolean {
return state.activeController.get() == BirdAirBehaviour.KEY
&& entity.onGround()
&& state.timeTransitioned.get() + 20 < entity.level().gameTime
}
private fun shouldTransitionToAir(
state: JumpToFlightCompositeState,
entity: PokemonEntity,
driver: Player
): Boolean {
return state.activeController.get() == GenericLandBehaviour.KEY
&& driver.jumping
&& state.timeTransitioned.get() + 20 < entity.level().gameTime
}
override fun pose(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): PoseType {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.pose(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.pose(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun speed(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.speed(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.speed(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotation(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotation(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.rotation(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun velocity(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.velocity(settings.land, state.landState, vehicle, driver, input)
BirdAirBehaviour.KEY -> birdBehaviour.velocity(settings.bird, state.flightState, vehicle, driver, input)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun angRollVel(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.angRollVel(
settings.land,
state.landState,
vehicle,
driver,
deltaTime
)
BirdAirBehaviour.KEY -> birdBehaviour.angRollVel(
settings.bird,
state.flightState,
vehicle,
driver,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotationOnMouseXY(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotationOnMouseXY(
settings.land,
state.landState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
BirdAirBehaviour.KEY -> birdBehaviour.rotationOnMouseXY(
settings.bird,
state.flightState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun canJump(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.canJump(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.canJump(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun setRideBar(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.setRideBar(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.setRideBar(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun jumpForce(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.jumpForce(
settings.land,
state.landState,
vehicle,
driver,
jumpStrength
)
BirdAirBehaviour.KEY -> birdBehaviour.jumpForce(
settings.bird,
state.flightState,
vehicle,
driver,
jumpStrength
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun gravity(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.gravity(settings.land, state.landState, vehicle, regularGravity)
BirdAirBehaviour.KEY -> birdBehaviour.gravity(settings.bird, state.flightState, vehicle, regularGravity)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rideFovMultiplier(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rideFovMultiplier(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.rideFovMultiplier(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useAngVelSmoothing(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useAngVelSmoothing(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.useAngVelSmoothing(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useRidingAltPose(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useRidingAltPose(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.useRidingAltPose(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun inertia(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.inertia(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.inertia(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRoll(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRoll(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.shouldRoll(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun turnOffOnGround(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.turnOffOnGround(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.turnOffOnGround(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun dismountOnShift(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.dismountOnShift(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.dismountOnShift(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePokemonHead(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePokemonHead(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.shouldRotatePokemonHead(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePlayerHead(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePlayerHead(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.shouldRotatePlayerHead(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun createDefaultState() = JumpToFlightCompositeState()
}
class JumpToFlightCompositeSettings : RidingBehaviourSettings {
override val key = JumpToFlightCompositeBehaviour.KEY
var bird: BirdAirSettings = BirdAirSettings()
private set
var land: GenericLandSettings = GenericLandSettings()
private set
var minimumSpeed: Expression = "0.5".asExpression()
private set
var minimumJump: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
bird.encode(buffer)
land.encode(buffer)
buffer.writeExpression(minimumSpeed)
buffer.writeExpression(minimumJump)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
bird.decode(buffer)
land.decode(buffer)
minimumSpeed = buffer.readExpression()
minimumJump = buffer.readExpression()
}
}
class JumpToFlightCompositeState : RidingBehaviourState {
var activeController = ridingState(GenericLandBehaviour.KEY, Side.CLIENT)
var currSpeed = ridingState(0.0, Side.BOTH)
var timeTransitioned = ridingState(-100L, Side.BOTH)
var landState = GenericLandState()
var flightState = BirdAirState()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(activeController.get())
landState.encode(buffer)
flightState.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
activeController.set(buffer.readResourceLocation(), forced = true)
landState.decode(buffer)
flightState.decode(buffer)
}
override fun reset() {
activeController.set(GenericLandBehaviour.KEY, forced = true)
timeTransitioned.set(-100L, forced = true)
currSpeed.set(0.0, forced = true)
}
override fun toString(): String {
return "JumpToFlightCompositeState(activeController=${activeController.get()}, landState=$landState, flightState=$flightState, currSpeed=${currSpeed.get()}, timeTransitioned=${timeTransitioned.get()})"
}
override fun copy() = JumpToFlightCompositeState().also {
it.activeController.set(activeController.get(), forced = true)
it.landState = landState.copy()
it.flightState = flightState.copy()
it.currSpeed.set(currSpeed.get(), forced = true)
it.timeTransitioned.set(timeTransitioned.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is JumpToFlightCompositeState) return false
if (activeController != previous.activeController) return true
if (landState.shouldSync(previous.landState)) return true
if (flightState.shouldSync(previous.flightState)) return true
return false
}
}
@@ -1,450 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readExpression
import com.cobblemon.mod.common.util.writeExpression
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class RunToJetCompositeBehaviour : RidingBehaviour<RunToJetCompositeSettings, RunToJetCompositeState> {
companion object {
val KEY = cobblemonResource("composite/run_to_jet")
}
override val key = KEY
val landBehaviour: GenericLandBehaviour = GenericLandBehaviour()
val jetBehaviour: JetAirBehaviour = JetAirBehaviour()
override fun tick(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val flightState = state.flightState
val groundState = state.landState
if (shouldTransitionToGround(state, vehicle, driver)) {
groundState.currSpeed = flightState.currSpeed
groundState.stamina = flightState.stamina
groundState.rideVel = flightState.rideVel
state.activeController.set(GenericLandBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
state.timeTransitioned.set(vehicle.level().gameTime)
} else if (shouldTransitionToAir(state, vehicle, driver, input)) {
flightState.currSpeed = groundState.currSpeed
flightState.stamina = groundState.stamina
flightState.rideVel = groundState.rideVel
state.activeController.set(JetAirBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
state.timeTransitioned.set(vehicle.level().gameTime)
}
}
private fun shouldTransitionToGround(
state: RunToJetCompositeState,
entity: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() != JetAirBehaviour.KEY) return false
if (state.timeTransitioned.get() + 20 >= entity.level().gameTime) return false
return driver.isSprinting || entity.onGround()
}
private fun shouldTransitionToAir(
state: RunToJetCompositeState,
entity: PokemonEntity,
driver: Player,
input: Vec3
): Boolean {
if (state.activeController.get() != GenericLandBehaviour.KEY) return false
if (state.timeTransitioned.get() + 20 >= entity.level().gameTime) return false
return driver.isSprinting && input.z > 0.5
}
override fun isActive(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun pose(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): PoseType {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.pose(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.pose(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun speed(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.speed(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.speed(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotation(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotation(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.rotation(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun velocity(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.velocity(settings.land, state.landState, vehicle, driver, input)
JetAirBehaviour.KEY -> jetBehaviour.velocity(settings.jet, state.flightState, vehicle, driver, input)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun angRollVel(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.angRollVel(
settings.land,
state.landState,
vehicle,
driver,
deltaTime
)
JetAirBehaviour.KEY -> jetBehaviour.angRollVel(settings.jet, state.flightState, vehicle, driver, deltaTime)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotationOnMouseXY(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotationOnMouseXY(
settings.land,
state.landState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
JetAirBehaviour.KEY -> jetBehaviour.rotationOnMouseXY(
settings.jet,
state.flightState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun canJump(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.canJump(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.canJump(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun setRideBar(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.setRideBar(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.setRideBar(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun jumpForce(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.jumpForce(settings.land, state.landState, vehicle, driver, jumpStrength)
JetAirBehaviour.KEY -> jetBehaviour.jumpForce(settings.jet, state.flightState, vehicle, driver, jumpStrength)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun gravity(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.gravity(settings.land, state.landState, vehicle, regularGravity)
JetAirBehaviour.KEY -> jetBehaviour.gravity(settings.jet, state.flightState, vehicle, regularGravity)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rideFovMultiplier(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rideFovMultiplier(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.rideFovMultiplier(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useAngVelSmoothing(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useAngVelSmoothing(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.useAngVelSmoothing(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useRidingAltPose(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useRidingAltPose(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.useRidingAltPose(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun inertia(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.inertia(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.inertia(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRoll(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRoll(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.shouldRoll(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun turnOffOnGround(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.turnOffOnGround(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.turnOffOnGround(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun dismountOnShift(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.dismountOnShift(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.dismountOnShift(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePokemonHead(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePokemonHead(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.shouldRotatePokemonHead(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePlayerHead(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePlayerHead(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.shouldRotatePlayerHead(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun createDefaultState() = RunToJetCompositeState()
}
class RunToJetCompositeSettings : RidingBehaviourSettings {
override val key = RunToJetCompositeBehaviour.KEY
var jet: JetAirSettings = JetAirSettings()
private set
var land: GenericLandSettings = GenericLandSettings()
private set
var minimumSpeed: Expression = "0.5".asExpression()
private set
var minimumJump: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
jet.encode(buffer)
land.encode(buffer)
buffer.writeExpression(minimumSpeed)
buffer.writeExpression(minimumJump)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
jet.decode(buffer)
land.decode(buffer)
minimumSpeed = buffer.readExpression()
minimumJump = buffer.readExpression()
}
}
class RunToJetCompositeState : RidingBehaviourState {
var activeController = ridingState(GenericLandBehaviour.KEY, Side.CLIENT)
var landState: GenericLandState = GenericLandState()
var flightState: JetAirState = JetAirState()
var currSpeed = ridingState(0.0, Side.BOTH)
var timeTransitioned = ridingState(-100L, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(activeController.get())
landState.encode(buffer)
flightState.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
activeController.set(buffer.readResourceLocation(), forced = true)
landState.decode(buffer)
flightState.decode(buffer)
}
override fun reset() {
activeController.set(GenericLandBehaviour.KEY, forced = true)
timeTransitioned.set(-100L, forced = true)
currSpeed.set(0.0, forced = true)
}
override fun toString(): String {
return "RunToJetCompositeState(activeController=${activeController.get()}, landState=$landState, flightState=$flightState, currSpeed=${currSpeed.get()}, timeTransitioned=${timeTransitioned.get()})"
}
override fun copy() = RunToJetCompositeState().also {
it.activeController.set(activeController.get(), forced = true)
it.landState = landState.copy()
it.flightState = flightState.copy()
it.currSpeed.set(currSpeed.get(), forced = true)
it.timeTransitioned.set(timeTransitioned.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is RunToJetCompositeState) return false
if (activeController != previous.activeController) return true
if (landState.shouldSync(previous.landState)) return true
if (flightState.shouldSync(previous.flightState)) return true
return false
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -33,6 +34,7 @@ class SwimDashBehaviour : RidingBehaviour<SwimDashSettings, SwimDashState> {
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<SwimDashSettings, SwimDashState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.isSwimming && entity.entityData.get(PokemonEntity.MOVING) })
@@ -217,7 +219,7 @@ class SwimDashBehaviour : RidingBehaviour<SwimDashSettings, SwimDashState> {
return false
}
override fun createDefaultState() = SwimDashState()
override fun createDefaultState(settings: SwimDashSettings) = SwimDashState()
}
class SwimDashSettings : RidingBehaviourSettings {
@@ -227,6 +229,7 @@ class SwimDashSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeFloat(dashSpeed)
}
@@ -235,14 +238,12 @@ class SwimDashSettings : RidingBehaviourSettings {
}
}
class SwimDashState : RidingBehaviourState {
class SwimDashState : RidingBehaviourState() {
var dashing = ridingState(false, Side.BOTH)
var ticks = ridingState(0, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun reset() {
super.reset()
dashing.set(false, forced = true)
ticks.set(0, forced = true)
}
@@ -252,9 +253,9 @@ class SwimDashState : RidingBehaviourState {
}
override fun copy() = SwimDashState().also {
it.rideVelocity.set(rideVelocity.get(), forced = true)
it.stamina.set(stamina.get(), forced = true)
it.dashing.set(dashing.get(), forced = true)
it.ticks.set(ticks. get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState) = false
}
@@ -53,6 +53,7 @@ class VehicleLandBehaviour : RidingBehaviour<VehicleLandSettings, VehicleLandSta
}
override val key = KEY
override val style = RidingStyle.LAND
val poseProvider = PoseProvider<VehicleLandSettings, VehicleLandState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
@@ -265,7 +266,7 @@ class VehicleLandBehaviour : RidingBehaviour<VehicleLandSettings, VehicleLandSta
return false
}
override fun createDefaultState() = VehicleLandState()
override fun createDefaultState(settings: VehicleLandSettings) = VehicleLandState()
}
class VehicleLandSettings : RidingBehaviourSettings {
@@ -296,6 +297,7 @@ class VehicleLandSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -324,14 +326,12 @@ class VehicleLandSettings : RidingBehaviourSettings {
}
}
class VehicleLandState : RidingBehaviourState {
class VehicleLandState : RidingBehaviourState() {
var currSpeed = ridingState(0.0, Side.BOTH)
var deltaRotation = ridingState(Vec2.ZERO, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun reset() {
super.reset()
currSpeed.set(0.0, forced = true)
deltaRotation.set(Vec2.ZERO, forced = true)
}
@@ -341,9 +341,9 @@ class VehicleLandState : RidingBehaviourState {
}
override fun copy() = VehicleLandState().also {
it.rideVelocity.set(rideVelocity.get(), forced = true)
it.stamina.set(stamina.get(), forced = true)
it.currSpeed.set(currSpeed.get(), forced = true)
it.deltaRotation.set(deltaRotation.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState) = false
}
@@ -0,0 +1,426 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types.composite
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.CompositeRidingStrategies
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.adapters.RidingBehaviourSettingsAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class CompositeBehaviour : RidingBehaviour<CompositeSettings, CompositeState> {
companion object {
val KEY = cobblemonResource("composite")
}
override val key = KEY
override val style = RidingStyle.COMPOSITE
override fun createDefaultState(settings: CompositeSettings): CompositeState {
val defaultBehaviour = RidingBehaviours.get(settings.defaultBehaviour.key)
val defaultState = defaultBehaviour.createDefaultState(settings.defaultBehaviour)
val alternateBehaviour = RidingBehaviours.get(settings.alternateBehaviour.key)
val alternativeState = alternateBehaviour.createDefaultState(settings.alternateBehaviour)
return CompositeState(
defaultBehaviour = settings.defaultBehaviour.key,
defaultBehaviourState = defaultState,
alternateBehaviourState = alternativeState
)
}
fun <T> chooseBehaviour(
settings: CompositeSettings,
state: CompositeState,
action: (behaviour: RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>, settings: RidingBehaviourSettings, state: RidingBehaviourState) -> T
): T {
val defaultBehaviour = RidingBehaviours.get(settings.defaultBehaviour.key)
val alternativeBehaviour = RidingBehaviours.get(settings.alternateBehaviour.key)
return when (state.activeController.get()) {
settings.defaultBehaviour.key -> action(
defaultBehaviour,
settings.defaultBehaviour,
state.defaultBehaviourState
)
settings.alternateBehaviour.key -> action(
alternativeBehaviour,
settings.alternateBehaviour,
state.alternateBehaviourState
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun tick(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val strategy = CompositeRidingStrategies.get(settings.transitionStrategy)
strategy.tick(settings, state, state.defaultBehaviourState, state.alternateBehaviourState, vehicle, driver, input)
}
override fun clampPassengerRotation(
settings: CompositeSettings,
state: CompositeState,
entity: PokemonEntity,
driver: LivingEntity
) {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.clampPassengerRotation(behaviourSettings, behaviourState, entity, driver)
}
}
override fun updatePassengerRotation(
settings: CompositeSettings,
state: CompositeState,
entity: PokemonEntity,
driver: LivingEntity
) {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.updatePassengerRotation(behaviourSettings, behaviourState, entity, driver)
}
}
override fun shouldRotatePlayerHead(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.shouldRotatePlayerHead(behaviourSettings, behaviourState, vehicle)
}
}
override fun shouldRotatePokemonHead(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.shouldRotatePokemonHead(behaviourSettings, behaviourState, vehicle)
}
}
override fun dismountOnShift(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.dismountOnShift(behaviourSettings, behaviourState, vehicle)
}
}
override fun turnOffOnGround(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.turnOffOnGround(behaviourSettings, behaviourState, vehicle)
}
}
override fun shouldRoll(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.shouldRoll(behaviourSettings, behaviourState, vehicle)
}
}
override fun inertia(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Double {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.inertia(behaviourSettings, behaviourState, vehicle)
}
}
override fun useRidingAltPose(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.useRidingAltPose(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun useAngVelSmoothing(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.useAngVelSmoothing(behaviourSettings, behaviourState, vehicle)
}
}
override fun rideFovMultiplier(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.rideFovMultiplier(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun gravity(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.gravity(behaviourSettings, behaviourState, vehicle, regularGravity)
}
}
override fun jumpForce(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.jumpForce(behaviourSettings, behaviourState, vehicle, driver, jumpStrength)
}
}
override fun setRideBar(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.setRideBar(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun canJump(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.canJump(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun rotationOnMouseXY(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.rotationOnMouseXY(
behaviourSettings,
behaviourState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
}
}
override fun angRollVel(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.angRollVel(behaviourSettings, behaviourState, vehicle, driver, deltaTime)
}
}
override fun velocity(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.velocity(behaviourSettings, behaviourState, vehicle, driver, input)
}
}
override fun rotation(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.rotation(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun speed(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.speed(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun pose(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): PoseType {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.pose(behaviourSettings, behaviourState, vehicle)
}
}
override fun isActive(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.isActive(behaviourSettings, behaviourState, vehicle)
}
}
}
open class CompositeSettings : RidingBehaviourSettings {
lateinit var transitionStrategy: ResourceLocation
private set
lateinit var defaultBehaviour: RidingBehaviourSettings
private set
lateinit var alternateBehaviour: RidingBehaviourSettings
private set
override val key: ResourceLocation = CompositeBehaviour.KEY
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeResourceLocation(transitionStrategy)
defaultBehaviour.encode(buffer)
alternateBehaviour.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
transitionStrategy = buffer.readResourceLocation()
val defaultBehaviourKey = buffer.readResourceLocation()
defaultBehaviour = RidingBehaviourSettingsAdapter.types[defaultBehaviourKey]?.getConstructor()?.newInstance()
?: error("Unknown controller key: $key")
defaultBehaviour.decode(buffer)
val alternativeBehaviourKey = buffer.readResourceLocation()
alternateBehaviour =
RidingBehaviourSettingsAdapter.types[alternativeBehaviourKey]?.getConstructor()?.newInstance()
?: error("Unknown controller key: $key")
alternateBehaviour.decode(buffer)
}
}
class CompositeState(
private val defaultBehaviour: ResourceLocation,
val defaultBehaviourState: RidingBehaviourState,
val alternateBehaviourState: RidingBehaviourState
) : RidingBehaviourState() {
var activeController = ridingState(defaultBehaviour, Side.CLIENT)
var lastTransition = ridingState(-100L, Side.BOTH)
override val rideVelocity: SidedRidingState<Vec3>
get() = when (activeController.get()) {
defaultBehaviour -> defaultBehaviourState.rideVelocity
else -> alternateBehaviourState.rideVelocity
}
override val stamina: SidedRidingState<Float>
get() = when (activeController.get()) {
defaultBehaviour -> defaultBehaviourState.stamina
else -> alternateBehaviourState.stamina
}
override fun reset() {
super.reset()
activeController.set(defaultBehaviour, forced = true)
lastTransition.set(-100L, forced = true)
defaultBehaviourState.reset()
alternateBehaviourState.reset()
}
override fun copy(): CompositeState {
val state =
CompositeState(defaultBehaviour, defaultBehaviourState.copy(), alternateBehaviourState.copy())
state.activeController.set(activeController.get(), forced = true)
state.lastTransition.set(lastTransition.get(), forced = true)
state.rideVelocity.set(rideVelocity.get(), forced = true)
state.stamina.set(stamina.get(), forced = true)
return state
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is CompositeState) return false
if (previous.activeController.get() != activeController.get()) return true
if (defaultBehaviourState.shouldSync(previous.defaultBehaviourState)) return true
if (alternateBehaviourState.shouldSync(previous.alternateBehaviourState)) return true
return super.shouldSync(previous)
}
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeResourceLocation(activeController.get())
defaultBehaviourState.encode(buffer)
alternateBehaviourState.encode(buffer)
}
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
activeController.set(buffer.readResourceLocation(), forced = true)
defaultBehaviourState.decode(buffer)
alternateBehaviourState.decode(buffer)
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import net.minecraft.resources.ResourceLocation
object CompositeRidingStrategies {
val strategies = mutableMapOf<ResourceLocation, CompositeRidingStrategy<out CompositeSettings>>()
init {
register(RunStrategy.key, RunStrategy)
register(JumpStrategy.key, JumpStrategy)
register(FallStrategy.key, FallStrategy)
}
fun register(key: ResourceLocation, strategy: CompositeRidingStrategy<out CompositeSettings>) {
if (strategies.contains(key)) error("Strategy already registered to key $key")
strategies[key] = strategy
}
fun get(key: ResourceLocation): CompositeRidingStrategy<CompositeSettings> {
if (!strategies.contains(key)) error("Strategy not registered to key $key")
return strategies[key]!! as CompositeRidingStrategy<CompositeSettings>
}
}
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
interface CompositeRidingStrategy<T : CompositeSettings> {
val key: ResourceLocation
fun tick(
settings: T,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
)
fun transition(
vehicle: PokemonEntity,
settings: CompositeSettings,
state: CompositeState,
fromState: RidingBehaviourState,
toState: RidingBehaviourState,
toSettings: RidingBehaviourSettings
) {
toState.stamina.set(fromState.stamina.get())
toState.rideVelocity.set(fromState.rideVelocity.get())
fromState.reset()
state.activeController.set(toSettings.key)
state.lastTransition.set(vehicle.level().gameTime)
val behaviour = RidingBehaviours.get(toSettings.key)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, behaviour.style == RidingStyle.AIR)
}
}
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
object FallStrategy : CompositeRidingStrategy<FallCompositeSettings> {
override val key = cobblemonResource("strategy/fall")
override fun tick(
settings: FallCompositeSettings,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (shouldTransitionToDefault(state, settings.defaultBehaviour, vehicle)) {
transition(vehicle, settings, state, alternateState, defaultState, settings.defaultBehaviour)
} else if (shouldTransitionToAlternate(settings, state, settings.alternateBehaviour, vehicle, driver)) {
transition(vehicle, settings, state, defaultState, alternateState, settings.alternateBehaviour)
}
}
private fun shouldTransitionToDefault(
state: CompositeState,
defaultSettings: RidingBehaviourSettings,
vehicle: PokemonEntity
): Boolean {
if (state.activeController.get() == defaultSettings.key) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
if (!vehicle.onGround()) return false
val defaultBehaviour = RidingBehaviours.get(defaultSettings.key)
return defaultBehaviour.isActive(defaultSettings, state.defaultBehaviourState, vehicle)
}
private fun shouldTransitionToAlternate(
settings: FallCompositeSettings,
state: CompositeState,
alternateSettings: RidingBehaviourSettings,
vehicle: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() == alternateSettings.key) return false
if (!driver.jumping) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
val runtime = vehicle.runtime
val minFallingSpeed = runtime.resolveFloat(settings.minimumFallSpeed)
val minForwardSpeed = runtime.resolveFloat(settings.minimumForwardSpeed)
if (vehicle.deltaMovement.y < -minFallingSpeed) return false
if (vehicle.deltaMovement.horizontalDistance() < minForwardSpeed) return false
val alternativeBehaviour = RidingBehaviours.get(alternateSettings.key)
return alternativeBehaviour.isActive(alternateSettings, state.alternateBehaviourState, vehicle)
}
}
class FallCompositeSettings : CompositeSettings() {
override val key = FallStrategy.key
var minimumForwardSpeed: Expression = "0.0".asExpression()
private set
var minimumFallSpeed: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
super.encode(buffer)
buffer.writeExpression(minimumForwardSpeed)
buffer.writeExpression(minimumFallSpeed)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
super.decode(buffer)
minimumForwardSpeed = buffer.readExpression()
minimumFallSpeed = buffer.readExpression()
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
object JumpStrategy : CompositeRidingStrategy<CompositeSettings> {
override val key = cobblemonResource("strategy/jump")
override fun tick(
settings: CompositeSettings,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (shouldTransitionToDefault(state, settings.defaultBehaviour, vehicle)) {
transition(vehicle, settings, state, alternateState, defaultState, settings.defaultBehaviour)
} else if (shouldTransitionToAlternative(state, settings.alternateBehaviour, vehicle, driver)) {
transition(vehicle, settings, state, defaultState, alternateState, settings.alternateBehaviour)
}
}
private fun shouldTransitionToDefault(
state: CompositeState,
defaultSettings: RidingBehaviourSettings,
vehicle: PokemonEntity
): Boolean {
if (state.activeController.get() == defaultSettings.key) return false
if (!vehicle.onGround()) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
val defaultBehaviour = RidingBehaviours.get(defaultSettings.key)
return defaultBehaviour.isActive(defaultSettings, state.defaultBehaviourState, vehicle)
}
private fun shouldTransitionToAlternative(
state: CompositeState,
alternativeSettings: RidingBehaviourSettings,
vehicle: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() == alternativeSettings.key) return false
if (!driver.jumping) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
val alternativeBehaviour = RidingBehaviours.get(alternativeSettings.key)
return alternativeBehaviour.isActive(alternativeSettings, state.alternateBehaviourState, vehicle)
}
}
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
object RunStrategy : CompositeRidingStrategy<CompositeSettings> {
override val key = cobblemonResource("strategy/run")
override fun tick(
settings: CompositeSettings,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (shouldTransitionToDefault(state, settings.defaultBehaviour, vehicle, driver)) {
transition(vehicle, settings, state, alternateState, defaultState, settings.defaultBehaviour)
}
else if (shouldTransitionToAlternate(state, settings.alternateBehaviour, vehicle, driver, input)) {
transition(vehicle, settings, state, defaultState, alternateState, settings.alternateBehaviour)
}
}
private fun shouldTransitionToDefault(
state: CompositeState,
defaultSettings: RidingBehaviourSettings,
entity: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() == defaultSettings.key) return false
if (!entity.onGround()) return false
if (state.lastTransition.get() + 20 >= entity.level().gameTime) return false
val defaultBehaviour = RidingBehaviours.get(defaultSettings.key)
val ret = defaultBehaviour.isActive(defaultSettings, state.defaultBehaviourState, entity)
return ret
}
private fun shouldTransitionToAlternate(
state: CompositeState,
alternativeSettings: RidingBehaviourSettings,
entity: PokemonEntity,
driver: Player,
input: Vec3
): Boolean {
if (state.activeController.get() == alternativeSettings.key) return false
if (state.lastTransition.get() + 20 >= entity.level().gameTime) return false
val alternativeBehaviour = RidingBehaviours.get(alternativeSettings.key)
return driver.isSprinting && input.z > 0.5 && alternativeBehaviour.isActive(alternativeSettings, state.alternateBehaviourState, entity)
}
}
@@ -0,0 +1,143 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.util
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
/**
* Class to handle the updating and containment of ride data used in animation.
*
* @author Jackowes
* @since April 7th, 2025
*/
class RidingAnimationData
{
var prevOrientation: Matrix3f = Matrix3f()
var prevRot: Vec3 = Vec3.ZERO
var velocitySpring: Vec3Spring = Vec3Spring()
var rotSpring: Vec3Spring = Vec3Spring()
var rotDeltaSpring: Vec3Spring = Vec3Spring()
var localVelocitySpring: Vec3Spring = Vec3Spring()
fun update(entity: PokemonEntity) {
var currRot = Vec3.ZERO
var angDelta = Vec3.ZERO
// val stiffness = 90.0
// val damping = 18.0
val stiffness = 16.0
val damping = 8.0
// Update velocity first
val currentVelocity = Vec3(
entity.x - entity.xOld,
entity.y - entity.yOld,
entity.z - entity.zOld
)
val r = entity.ifRidingAvailableSupply(false) { behaviour, settings, state ->
behaviour.shouldRoll(settings, state, entity);
}
if( r ) {
//TODO: should this return?
val controller = (entity.firstPassenger as? OrientationControllable)?.orientationController ?: return
val orientation = controller.orientation ?: Matrix3f()
val currPitch = controller.pitch
val currYaw = controller.yaw
val currRoll = controller.roll
currRot = Vec3(currPitch.toDouble(), currYaw.toDouble(), currRoll.toDouble())
val currOrientation = orientation
/******************************************************
* Calculate current 3d euler rotation deltas in the
* entities local space
*****************************************************/
// Get current and previous orientation as quaternions
val currQuat = Quaternionf().setFromUnnormalized(currOrientation)
val prevQuat = Quaternionf().setFromUnnormalized(prevOrientation)
// Compute deltaQuat = current * inverse(previous)
val deltaQuat = Quaternionf(currQuat).mul(Quaternionf(prevQuat).invert())
// Transform delta into the local space of the current orientation
val localDeltaQuat = Quaternionf(currQuat).invert().mul(deltaQuat).mul(currQuat)
// Convert delta rotation to Euler angles
val euler = Vector3f()
localDeltaQuat.getEulerAnglesXYZ(euler) // Angles are in radians
// Convert to degrees
val pitchDegrees = Math.toDegrees(euler.x.toDouble()) // Rotation around X axis = pitch
val yawDegrees = Math.toDegrees(euler.y.toDouble()) // Rotation around Y axis = yaw
val rollDegrees = Math.toDegrees(euler.z.toDouble()) // Rotation around Z axis = roll
//Scale rotation delta by 20 to represent degree per second instead of tick
angDelta = Vec3(pitchDegrees, yawDegrees, rollDegrees).scale(20.0)
/******************************************************
* Calculate ride local velocity
*****************************************************/
val velocityWorldF = Vector3f(currentVelocity.x.toFloat(), currentVelocity.y.toFloat(), currentVelocity.z.toFloat())
val localVelocityF = Matrix3f(orientation).transpose().transform(velocityWorldF)
val localVelocity = Vec3(localVelocityF.x.toDouble(), localVelocityF.y.toDouble(), localVelocityF.z.toDouble())
localVelocitySpring.update(localVelocity, stiffness, damping)
// Update previous values
prevOrientation.set(currOrientation)
} else {
val currPitch = entity.xRot
val currYaw = entity.yRot
val currRoll = 0.0f
currRot = Vec3(currPitch.toDouble(), currYaw.toDouble(), currRoll.toDouble())
//Scale rotation delta by 20 to represent degree per second instead of tick
angDelta = Vec3(
(currRot.x - prevRot.x),
Mth.degreesDifference(currRot.y.toFloat(), prevRot.y.toFloat()).toDouble(),
Mth.degreesDifference(currRot.z.toFloat(), prevRot.z.toFloat()).toDouble()
).scale(20.0)
/******************************************************
* Calculate ride local velocity
*****************************************************/
val yaw360 = -1.0 * (entity.yRot + 360.0f) % 360.0f
val orientationNonRollable = Matrix3f().rotateY(yaw360.toRadians())
//Convert to Vector3f
var velocityWorldF = Vector3f(currentVelocity.x.toFloat(), currentVelocity.y.toFloat(), currentVelocity.z.toFloat())
val localVelocityF = Matrix3f(orientationNonRollable).transpose().transform(velocityWorldF)
val localVelocity = Vec3(localVelocityF.x.toDouble(), localVelocityF.y.toDouble(), localVelocityF.z.toDouble())
localVelocitySpring.update(localVelocity, stiffness, damping)
}
/******************************************************
* Update springs
*****************************************************/
rotDeltaSpring.update(angDelta, stiffness, damping)
velocitySpring.update(currentVelocity, stiffness, damping)
rotSpring.update(currRot, stiffness, damping)
prevRot = currRot
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.riding.util
import net.minecraft.world.phys.Vec3
import kotlin.math.min
/**
* A spring-based smoother for Vec3 values, designed for applying damped spring motion to riding data.
* Stores the previous and current values, along with a history buffer for lookback-based interpolation.
*
* @author Jackowes
* @since March 27th, 2025
*/
class Vec3Spring(
var value: Vec3 = Vec3.ZERO,
var velocity: Vec3 = Vec3.ZERO
) {
val history = ArrayDeque<Vec3>()
//Hold up to a seconds worth of values
val lookBackSize = 20
fun update(target: Vec3, stiffness: Double, damping: Double) {
//Hooke's Law f = kx where:
//f is force
//k is the spring constant or stiffness of this spring
//x is the distance from rest and in this case the difference between the most recent
//rotation delta ( the target ) and the springs current value for delta rot
val force = target.subtract(value).scale(stiffness)
//Now calculate acceleration and apply damping
val accel = force.subtract(velocity.scale(damping))
velocity = velocity.add(accel.scale(1.0/20.0))
value = value.add(velocity.scale(1.0/20.0))
history.addFirst(value)
//Adding one since if we want to check max look back point it needs something to interp with.
if( history.size > lookBackSize + 1) {
history.removeLast()
}
}
fun getInterpolated(partialTick: Double, lookBackTick: Int): Vec3 {
if (history.size < 2) {
return value // or Vec3.ZERO if you prefer
}
val tick = min(lookBackTick, history.size - 2)
var ret = Vec3.ZERO
for( i in 0..tick) {
val older = history.get(i + 1).scale(1.0)
val newer = history.get(i).scale(1.0)
ret = ret.add(older.add(newer.subtract(older).scale(partialTick)))
}
return ret.scale(1.0/(tick+1))
}
}
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
import net.minecraft.server.level.ServerLevel
import java.util.UUID
import net.minecraft.server.level.ServerPlayer
@@ -32,24 +33,45 @@ object CobblemonWorldSpawnerManager : SpawnerManager() {
init {
PlatformEvents.SERVER_PLAYER_LOGIN.subscribe { this.onPlayerLogin(it.player) }
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe { this.onPlayerLogout(it.player) }
PlatformEvents.CHANGE_DIMENSION.subscribe { this.onDimensionChange(it.player, it.origin, it.destination) }
}
fun onPlayerLogin(player: ServerPlayer) {
// Disables spawning
if (!Cobblemon.config.enableSpawning || server()?.gameRules?.getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING) == false) {
if (!Cobblemon.config.enableSpawning || player.level().gameRules.getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING) == false) {
return;
}
val spawner = PlayerSpawnerFactory.create(this, player)
spawnersForPlayers[player.uuid] = spawner
registerSpawner(spawner)
registerPlayerSpawner(player)
}
fun onPlayerLogout(player: ServerPlayer) {
val spawner = spawnersForPlayers[player.uuid]
if (spawner != null) {
spawnersForPlayers.remove(player.uuid)
unregisterSpawner(spawner)
unregisterPlayerSpawner(player)
}
fun onDimensionChange(player: ServerPlayer, origin: ServerLevel?, destination: ServerLevel?) {
fun getSpawnRule(level: ServerLevel?) = level?.gameRules?.getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING)
if (!Cobblemon.config.enableSpawning || getSpawnRule(origin) == getSpawnRule(destination)) {
return
}
val spawnerAction = if (destination?.gameRules?.getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING) == false) {
::unregisterPlayerSpawner
} else {
::registerPlayerSpawner
}
spawnerAction(player)
}
private fun unregisterPlayerSpawner(player: ServerPlayer) {
spawnersForPlayers.remove(player.uuid)?.let { unregisterSpawner(it) }
}
private fun registerPlayerSpawner(player: ServerPlayer) {
PlayerSpawnerFactory.create(this, player).also {
spawnersForPlayers[player.uuid] = it
registerSpawner(it)
}
}
}
@@ -71,10 +71,15 @@ open class SpawnerManager {
open fun onServerTick() {
// Disables spawning
if (!Cobblemon.config.enableSpawning || server()?.gameRules?.getBoolean(DO_POKEMON_SPAWNING) == false) {
if (!Cobblemon.config.enableSpawning) {
return
}
influences.removeIf { it.isExpired() }
getSpawnersOfType<TickingSpawner>().forEach(TickingSpawner::tick)
getSpawnersOfType<TickingSpawner>().forEach {
if (it.getCauseEntity()?.level()?.gameRules?.getBoolean(DO_POKEMON_SPAWNING) == false) {
return@forEach
}
it.tick()
}
}
}
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
/**
* This class is responsible for setting up the animation state of a Pokemon entity before it begins to render.
*
* Sometimes we depend on the animation state of the Pokemon to be set up before we begin rendering it, so this class
* allows us to do that. It also caches which Pokemon have been pre-animated to avoid doing it multiple times.
*
* @author landonjw
*/
object MountedPokemonAnimationRenderController {
private val forcedDeltas = mutableMapOf<Int, Float>()
fun setup(pokemon: PokemonEntity, partialTickTime: Float) {
if (forcedDeltas.contains(pokemon.id)) return
val delegate = pokemon.delegate as? PokemonClientDelegate ?: return
val model = delegate.currentModel ?: return
if (!model.isReadyForAnimation()) return
val entityPos = Vec3(
Mth.lerp(partialTickTime.toDouble(), pokemon.xOld, pokemon.x),
Mth.lerp(partialTickTime.toDouble(), pokemon.yOld, pokemon.y),
Mth.lerp(partialTickTime.toDouble(), pokemon.zOld, pokemon.z)
)
val f = Mth.rotLerp(partialTickTime, pokemon.yBodyRotO, pokemon.yBodyRot)
val g = Mth.rotLerp(partialTickTime, pokemon.yHeadRotO, pokemon.yHeadRot)
var h = g - f
val j = Mth.lerp(partialTickTime, pokemon.xRotO, pokemon.xRot)
h = Mth.wrapDegrees(h)
var l = 0.0f
var m = 0.0f
if (!pokemon.isPassenger && pokemon.isAlive) {
l = pokemon.walkAnimation.speed(partialTickTime)
m = pokemon.walkAnimation.position(partialTickTime)
if (pokemon.isBaby) {
m *= 3.0f
}
if (l > 1.0f) {
l = 1.0f
}
}
delegate.updatePartialTicks(partialTickTime)
delegate.updateLocatorPosition(entityPos)
delegate.currentModel?.applyAnimations(pokemon, delegate, l, m, partialTickTime, j, h)
forcedDeltas[pokemon.id] = partialTickTime
}
fun getPartialTick(pokemon: PokemonEntity) : Float? {
return forcedDeltas[pokemon.id]
}
/**
* Resets the prerendered list. This should be called in the render loop before we begin setting up any pokemon with `setup`.
*/
fun reset() {
forcedDeltas.clear()
}
}
@@ -58,8 +58,8 @@ class NPCClientDelegate : PosableState(), NPCSideDelegate {
override fun addToStruct(struct: QueryStruct) {
super.addToStruct(struct)
struct.addFunctions(functions.functions)
struct.addFunctions(ClientMoLangFunctions.clientFunctions)
struct.addFunctions(functions.functions)
runtime.environment.query.addFunctions(struct.functions)
}
}
@@ -340,14 +340,17 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
override fun addToStruct(struct: QueryStruct) {
super.addToStruct(struct)
struct.addFunctions(functions.functions)
struct.addFunctions(ClientMoLangFunctions.clientFunctions)
struct.addFunctions(functions.functions)
runtime.environment.query = struct
}
override fun updateAge(age: Int) {
this.age = age
}
override fun initialize(entity: PokemonEntity) {
this.currentEntity = entity
this.age = entity.tickCount
this.runtime.environment.query.addFunctions(mapOf(
"in_battle" to java.util.function.Function {
@@ -458,10 +458,11 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
formRightButton.render(context,mouseX, mouseY, delta)
val form = showableForms[selectedFormIndex]
val formName = if (form.displayForm.lowercase() == "normal") "" else "-${form.displayForm.lowercase().replace("-", "")}"
drawScaledTextJustifiedRight(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = lang("ui.pokedex.info.form.${form.displayForm.lowercase()}").bold(),
text = lang("ui.pokedex.info.form.${species}${formName}").bold(),
x = pX + 136,
y = pY + 15,
shadow = true
@@ -282,12 +282,12 @@ class PokedexScannerRenderer {
val effectiveIntervals = clamp(usageContext.transitionIntervals + (if (usageContext.scanningGuiOpen) 1 else -1) * tickDelta, 0F, 12F)
if (effectiveIntervals <= PokedexUsageContext.TRANSITION_INTERVALS) {
val scale = 1 + (if (effectiveIntervals <= 2) 0F else ((effectiveIntervals - 2) * 0.075F))
val scale = 1F + (if (effectiveIntervals <= 2) 0F else ((effectiveIntervals - 2) * 0.075F))
val centerX = (screenWidth - (BASE_WIDTH * scale)) / 2
val centerY = (screenHeight - (BASE_HEIGHT * scale)) / 2
val opacity = if (effectiveIntervals <= 2) 1F else (10F - (effectiveIntervals - 2F)) / 10F
val opacity = if (effectiveIntervals > 11) 0F else effectiveIntervals / PokedexUsageContext.TRANSITION_INTERVALS
blitk(matrixStack = matrices, texture = CobblemonClient.pokedexUsageContext.type.getTexturePath(), x = centerX / scale, y = centerY / scale, width = BASE_WIDTH, height = BASE_HEIGHT, scale = scale, alpha = opacity)
blitk(matrixStack = matrices, texture = SCAN_SCREEN, x = centerX / scale, y = centerY / scale, width = BASE_WIDTH, height = BASE_HEIGHT, scale = scale, alpha = opacity)
}
@@ -90,16 +90,17 @@ class HeldItemRenderer {
poseStack.mulPose(Axis.XP.rotationDegrees(90.0f))
}
ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, ItemDisplayContext.THIRD_PERSON_LEFT_HAND -> {
val isLeft = displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND
//For Minecraft player models
if (state is NPCClientDelegate) {
poseStack.mulPose(Axis.XP.rotationDegrees(-90.0F))
poseStack.mulPose(Axis.XP.rotationDegrees(-90.0f))
poseStack.translate(0.025f * if (isLeft) 1 else -1 , 0.0f, 0.0f)
}
//for T-Posing Models
else if (state is PokemonClientDelegate || state is FloatingState) {
poseStack.mulPose(Axis.YP.rotationDegrees(-90.0F))
poseStack.mulPose(Axis.ZP.rotationDegrees(90.0F))
poseStack.mulPose(Axis.YP.rotationDegrees(-90.0f * if (isLeft) -1f else 1f))
poseStack.mulPose(Axis.ZP.rotationDegrees(90.0f * if (isLeft) -1f else 1f))
}
poseStack.translate(0.025f * if (displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND) 1 else -1 , 0.0f, 0.0f)
}
ItemDisplayContext.HEAD -> {
if (state is NPCClientDelegate) {
@@ -8,10 +8,8 @@
package com.cobblemon.mod.common.client.render.models.blockbench
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.client.renderer.RenderType
import com.mojang.blaze3d.vertex.VertexConsumer
@@ -36,7 +34,6 @@ abstract class PosableEntityModel<T : Entity>(
val context: RenderContext = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
}
lateinit var posableModel: PosableModel
override fun renderToBuffer(
@@ -79,11 +76,25 @@ abstract class PosableEntityModel<T : Entity>(
) {
setupEntityTypeContext(entity)
if (entity is PosableEntity) {
val state = entity.delegate as PosableState
posableModel.applyAnimations(entity, state, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch)
val ticks = getTicksForAnimation(entity, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch)
posableModel.applyAnimations(entity, entity.delegate as PosableState, limbSwing, limbSwingAmount, ticks, headYaw, headPitch)
}
}
/**
* This is to support cases where the ageInTicks value that should go to the animator is not the same as the entity's
* normal value. This can happen in the case of riding where it has been rendered in a different part of the pipeline
* and we want to prevent stuttering / re-render it for a specific moment.
*/
open fun getTicksForAnimation(
entity: T,
limbSwing: Float,
limbSwingAmount: Float,
ageInTicks: Float,
headYaw: Float,
headPitch: Float
): Float = ageInTicks
open fun setupEntityTypeContext(entity: Entity?) {
entity?.let {
context.put(RenderContext.ENTITY, entity)
@@ -92,4 +103,4 @@ abstract class PosableEntityModel<T : Entity>(
}
}
}
}
}
@@ -48,6 +48,7 @@ import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
@@ -826,4 +827,6 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
condition = condition,
animations = { animations(it) }
)
fun isReadyForAnimation() = ::context.isInitialized
}
@@ -35,8 +35,10 @@ import com.cobblemon.mod.common.client.render.models.blockbench.quirk.ModelQuirk
import com.cobblemon.mod.common.client.render.models.blockbench.quirk.QuirkData
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.mojang.brigadier.StringReader
import com.mojang.brigadier.exceptions.CommandSyntaxException
import net.minecraft.client.Minecraft
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.client.resources.sounds.SimpleSoundInstance
@@ -130,8 +132,137 @@ abstract class PosableState : Schedulable {
/** A list of items to be rendered on a PosableModel during an animation */
val animationItems = mutableMapOf<String, ItemStack>()
/** All of the MoLang functions that can be expose current riding data. */
val ridingFunctions = QueryStruct(hashMapOf())
.addFunction("pitch") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickPitch = pokemon.ridingAnimationData.rotSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
val maxPitch = 90.0
return@addFunction DoubleValue((partialTickPitch / maxPitch).coerceIn(-1.0,1.0))
}
.addFunction("yaw") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickYaw = pokemon.ridingAnimationData.rotSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
val maxYaw = 180.0
return@addFunction DoubleValue((partialTickYaw / maxYaw).coerceIn(-1.0,1.0))
}
.addFunction("roll") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickRoll = pokemon.ridingAnimationData.rotSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val maxRoll = 180.0
return@addFunction DoubleValue((partialTickRoll / maxRoll).coerceIn(-1.0,1.0))
}
.addFunction("pitch_change") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickPitchDelta = pokemon.ridingAnimationData.rotDeltaSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
//TODO: hook back up the retrieval of the current behaviors stat for this and the following functions
val maxRotRate = 140.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SKILL)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickPitchDelta / maxRotRate).coerceIn(-1.0,1.0))
}
.addFunction("yaw_change") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickYawDelta = pokemon.ridingAnimationData.rotDeltaSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
//TODO: make this not hardcoded
val maxRotRate = 140.0 //pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SKILL)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickYawDelta / maxRotRate).coerceIn(-1.0,1.0))
}
.addFunction("roll_change") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickRollDelta = pokemon.ridingAnimationData.rotDeltaSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val maxRotRate = 140.0 //pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SKILL)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickRollDelta / maxRotRate).coerceIn(-1.0,1.0))
}
.addFunction("speed") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickSpeed = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).length()
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickSpeed / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_x") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickXVel = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickXVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_y") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickYVel = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickYVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_z") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_right") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.localVelocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0) * -1.0)
}
.addFunction("velocity_upward") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.localVelocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_forward") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.localVelocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0))
}
/** All of the MoLang functions that can be applied to something with this state. */
val functions = QueryStruct(hashMapOf())
val functions = QueryStruct(hashMapOf(
"riding" to java.util.function.Function { ridingFunctions },
"r" to java.util.function.Function { ridingFunctions }
))
.addFunction("anim_time") {
reusableAnimTime.value = animationSeconds.toDouble()
reusableAnimTime
@@ -141,26 +272,34 @@ abstract class PosableState : Schedulable {
.addFunction("has_entity") { DoubleValue(getEntity() != null) }
.addFunction("pose") { StringValue(currentPose ?: "") }
.addFunction("sound") { params ->
val entity = getEntity() ?: return@addFunction Unit
if (params.get<MoValue>(0) !is StringValue) {
return@addFunction Unit
}
val entity = getEntity()
val soundEvent = SoundEvent.createVariableRangeEvent(params.getString(0).asIdentifierDefaultingNamespace())
if (soundEvent != null) {
val volume = if (params.contains(1)) params.getDouble(1).toFloat() else 1F
val pitch = if (params.contains(2)) params.getDouble(2).toFloat() else 1F
Minecraft.getInstance().soundManager.play(
SimpleSoundInstance(soundEvent, SoundSource.NEUTRAL, volume, pitch, entity.level().random, entity.x, entity.y, entity.z)
)
if (entity != null) {
entity.level().playLocalSound(entity, soundEvent, entity.soundSource, volume, pitch)
} else {
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(soundEvent, volume, pitch))
}
}
}
.addFunction("render_item") { params ->
if (params.get<MoValue>(0) !is StringValue) return@addFunction Unit
val client = Minecraft.getInstance().connection ?: return@addFunction Unit
val result = ItemParser(client.registryAccess()).parse(StringReader(params.getString(0)))
val item = ItemStack(result.item)
item.applyComponents(result.components)
val item: ItemStack
try {
val client = Minecraft.getInstance().connection ?: return@addFunction Unit
val result = ItemParser(client.registryAccess()).parse(StringReader(params.getString(0)))
item = ItemStack(result.item)
item.applyComponents(result.components)
}
catch (_: CommandSyntaxException) {
return@addFunction Unit
}
val renderLocation = if (params.contains(1)) params.getString(1) else "item"
@@ -8,12 +8,16 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.PosableEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.phys.Vec3
class PosablePokemonEntityModel : PosableEntityModel<PokemonEntity>() {
override fun setupEntityTypeContext(entity: Entity?) {
@@ -26,4 +30,28 @@ class PosablePokemonEntityModel : PosableEntityModel<PokemonEntity>() {
.let { texture -> context.put(RenderContext.TEXTURE, texture) }
}
}
// TODO: This is a bit of a hack, but it works for now. We should find a better way to do this.
override fun getTicksForAnimation(
entity: PokemonEntity,
limbSwing: Float,
limbSwingAmount: Float,
ageInTicks: Float,
headYaw: Float,
headPitch: Float
): Float {
val delegate = entity.delegate as? PosableState
val forcedTick = MountedPokemonAnimationRenderController.getPartialTick(entity)
if (entity.passengers.isEmpty() || delegate == null || forcedTick == null) {
return ageInTicks
}
delegate.updatePartialTicks(forcedTick)
val entityPos = Vec3(
Mth.lerp(forcedTick.toDouble(), entity.xOld, entity.x),
Mth.lerp(forcedTick.toDouble(), entity.yOld, entity.y),
Mth.lerp(forcedTick.toDouble(), entity.zOld, entity.z)
)
delegate.updateLocatorPosition(entityPos)
return forcedTick
}
}
@@ -1,64 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class KangaskhanModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("kangaskhan")
override val head = getPart("head")
override var portraitScale = 1.7F
override var portraitTranslation = Vec3(-0.15, 1.1, 0.0)
override var profileScale = 0.7F
override var profileTranslation = Vec3(0.0, 0.65, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("kangaskhan", "blink")}
val blink2 = quirk { bedrockStateful("kangaskhan", "blink2")}
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink, blink2),
animations = arrayOf(
singleBoneLook(),
bedrock("kangaskhan", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink, blink2),
animations = arrayOf(
singleBoneLook(),
bedrock("kangaskhan", "ground_idle")
//bedrock("kangaskhan", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("kangaskhan", "faint") else null
}
@@ -1,72 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class GrovyleModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("grovyle")
override val head = getPart("head")
override val leftLeg = getPart("left_upper_leg")
override val rightLeg = getPart("right_upper_leg")
override var portraitScale = 2.31F
override var portraitTranslation = Vec3(-0.24, 1.29, 0.0)
override var profileScale = 0.66F
override var profileTranslation = Vec3(0.01, 0.87, 0.0)
//lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("grovyle", "cry") }
override fun registerPoses() {
//sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("grovyle", "sleep"))
//)
val blink = quirk { bedrockStateful("grovyle", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("grovyle", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("grovyle", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
)
)
}
//override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
//) = if (state.isNotPosedIn(sleep)) bedrockStateful("grovyle", "faint") else null
}
@@ -1,95 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MetagrossModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("metagross")
override var portraitScale = 1.1F
override var portraitTranslation = Vec3(-0.45, 0.5, 0.0)
override var profileScale = 0.4F
override var profileTranslation = Vec3(0.0, 1.0, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
override val cryAnimation = CryProvider { bedrockStateful("metagross", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("metagross", "blink")}
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("metagross", "sleep"))
)
standing = registerPose(
poseName = "stand",
poseTypes = PoseType.STATIONARY_POSES - PoseType.HOVER - PoseType.FLOAT + PoseType.UI_POSES,
condition = { !it.isBattling },
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "air_fly")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY - PoseType.SWIM,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("metagross", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("metagross", "faint") else null
}
@@ -1,72 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SceptileModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("sceptile")
override val head = getPart("head")
override val leftLeg = getPart("left_upper_leg")
override val rightLeg = getPart("right_upper_leg")
override var portraitScale = 2.34F
override var portraitTranslation = Vec3(-0.25, 2.22, 0.0)
override var profileScale = 0.63F
override var profileTranslation = Vec3(0.06, 0.91, 0.0)
lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("sceptile", "cry") }
override fun registerPoses() {
// sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("sceptile", "sleep"))
// )
val blink = quirk { bedrockStateful("sceptile", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sceptile", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sceptile", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
)
)
}
//override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
//) = if (state.isNotPosedIn(sleep)) bedrockStateful("sceptile", "faint") else null
}
@@ -1,66 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TreeckoModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("treecko")
override val head = getPart("head")
override var portraitScale = 2.25F
override var portraitTranslation = Vec3(0.02, 0.12, 0.0)
override var profileScale = 0.74F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("treecko", "cry") }
override fun registerPoses() {
//sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("treecko", "sleep"))
//)
val blink = quirk { bedrockStateful("treecko", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES + PoseType.SLEEP,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("treecko", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("treecko", "ground_walk"),
)
)
}
//override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
//) = if (state.isNotPosedIn(sleep)) bedrockStateful("treecko", "faint") else null
}
@@ -1,76 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen7
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MudsdaleModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
override val rootPart = root.registerChildWithAllChildren("mudsdale")
override val head = getPart("neck")
override val foreLeftLeg = getPart("leg_front_left")
override val foreRightLeg = getPart("leg_front_right")
override val hindLeftLeg = getPart("leg_back_left")
override val hindRightLeg = getPart("leg_back_right")
override var portraitScale = 1.5F
override var portraitTranslation = Vec3(-1.0, 1.76, 0.0)
override var profileScale = 0.5F
override var profileTranslation = Vec3(0.0, 1.0, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("mudsdale", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("mudsdale", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("mudsdale", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(disableY = true),
bedrock("mudsdale", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(disableY = true),
bedrock("mudsdale", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("mudsdale", "faint") else null
}
@@ -1,69 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SneaslerModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("sneasler")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 2.03F
override var portraitTranslation = Vec3(-0.44, 2.41, 0.0)
override var profileScale = 0.52F
override var profileTranslation = Vec3(0.0, 0.94, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("sneasler", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("sneasler", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sneasler", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sneasler", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
//bedrock("sneasler", "ground_walk")
)
)
}
}
@@ -287,7 +287,6 @@ object VaryingModelRepository {
inbuilt("kabuto", ::KabutoModel)
inbuilt("kabutops", ::KabutopsModel)
inbuilt("kadabra", ::KadabraModel)
inbuilt("kangaskhan", ::KangaskhanModel)
inbuilt("koffing", ::KoffingModel)
inbuilt("krabby", ::KrabbyModel)
inbuilt("lickitung", ::LickitungModel)
@@ -404,9 +403,6 @@ object VaryingModelRepository {
inbuilt("klinklang", :: KlinklangModel)
inbuilt("morelull", :: MorelullModel)
inbuilt("shiinotic", :: ShiinoticModel)
inbuilt("treecko", :: TreeckoModel)
inbuilt("grovyle", :: GrovyleModel)
inbuilt("sceptile", :: SceptileModel)
inbuilt("honedge", :: HonedgeModel)
inbuilt("spiritomb", :: SpiritombModel)
inbuilt("chespin", :: ChespinModel)
@@ -484,7 +480,6 @@ object VaryingModelRepository {
inbuilt("taillow", ::TaillowModel)
inbuilt("swellow", ::SwellowModel)
inbuilt("mudbray", ::MudbrayModel)
inbuilt("mudsdale", ::MudsdaleModel)
inbuilt("comfey", ::ComfeyModel)
inbuilt("tandemaus", ::TandemausModel)
inbuilt("maushold", ::MausholdModel)
@@ -642,7 +637,6 @@ object VaryingModelRepository {
inbuilt("gallade", ::GalladeModel)
inbuilt("beldum", ::BeldumModel)
inbuilt("metang", ::MetangModel)
inbuilt("metagross", ::MetagrossModel)
inbuilt("ursaluna", ::UrsalunaModel)
inbuilt("lechonk", ::LechonkModel)
inbuilt("oinkologne_male", ::OinkologneMaleModel)
@@ -702,7 +696,6 @@ object VaryingModelRepository {
inbuilt("qwilfish_hisuian", ::QwilfishHisuianModel)
inbuilt("overqwil", ::OverqwilModel)
inbuilt("sneasel_hisuian", ::SneaselHisuianModel)
inbuilt("sneasler", ::SneaslerModel)
inbuilt("petilil", ::PetililModel)
inbuilt("lilligant", ::LilligantModel)
inbuilt("petilil_hisui_bias", ::PetililHisuiBiasModel)
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.render.player
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.Rideable
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
@@ -20,6 +21,7 @@ import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.player.AbstractClientPlayer
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
import org.joml.AxisAngle4f
import org.joml.Matrix4f
import org.joml.Vector3f
@@ -40,12 +42,7 @@ object MountedPlayerRenderer {
//Positions player
if (locator != null) {
val locatorOffset = locator.matrix.getTranslation(Vector3f())
val center = Vector3f(0f, entity.bbHeight/2, 0f)
val locatorOffsetToCenter = locatorOffset.sub(center, Vector3f())
val offset = locatorOffsetToCenter.add(center, Vector3f()).sub(Vector3f(0f, player.bbHeight / 2, 0f))
matrix.translate(offset)
MountedPokemonAnimationRenderController.setup(entity, partialTicks)
//Undo seat position
val playerPos = Vec3(
@@ -61,20 +58,16 @@ object MountedPlayerRenderer {
)
matrix.translate(playerPos.subtract(entityPos).toVector3f().negate())
}
matrix.translate(locator.matrix.getTranslation(Vector3f()))
//Rotates player
if (player is OrientationControllable && player.orientationController.active && !disableRollableRenderDebug) {
val center = Vector3f(0f, player.bbHeight / 2, 0f)
val transformationMatrix = Matrix4f()
transformationMatrix.translate(center)
transformationMatrix.rotate(player.orientationController.getRenderOrientation(partialTicks))
transformationMatrix.translate(center.negate(Vector3f()))
//Pre-Undo Yaw
transformationMatrix.rotate(Axis.YP.rotationDegrees(yBodyRot+180f))
matrix.mul(transformationMatrix)
val offset = Vector3f(0f, player.bbHeight / 2, 0f).mul(-1f)
matrix.rotate(locator.matrix.getRotation(AxisAngle4f()))
matrix.rotate(Axis.YP.rotationDegrees(180 + yBodyRot))
matrix.translate(offset)
matrix.translate(Vector3f(0f, 0.35f, 0f))
}
matrix.translate(0f, 0.25f, 0f)
}
fun animate(
@@ -46,6 +46,9 @@ class CobblemonConfig {
var announceDropItems = true
@CobblemonConfigField(Category.Pokemon, lang = "default_drop_item_method")
var defaultDropItemMethod = ItemDropMethod.ON_ENTITY
@CobblemonConfigField(Category.Pokemon, lang = "drops_after_death_animation")
var dropAfterDeathAnimation = false
@CobblemonConfigField(Category.Pokemon, lang = "ambient_pokemon_cry_ticks")
@LastChangedVersion("1.4.0")
var ambientPokemonCryTicks = 1080
@@ -49,6 +49,8 @@ import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.events.SelectDriverEvent
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.api.riding.util.RidingAnimationData
import com.cobblemon.mod.common.api.riding.util.Vec3Spring
import com.cobblemon.mod.common.api.scheduling.Schedulable
import com.cobblemon.mod.common.api.scheduling.SchedulingTracker
import com.cobblemon.mod.common.api.scheduling.afterOnServer
@@ -251,6 +253,7 @@ open class PokemonEntity(
var enablePoseTypeRecalculation = true
val ridingAnimationData: RidingAnimationData = RidingAnimationData()
var previousRidingState: RidingBehaviourState? = null
var ridingState: RidingBehaviourState? = null
@@ -283,9 +286,9 @@ open class PokemonEntity(
ridingBehaviourSettings = null
if (pokemon.riding.behaviour == null) return
riding = RidingBehaviours.get(pokemon.riding.behaviour!!.key) as RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>?
ridingState = riding!!.createDefaultState()
riding = RidingBehaviours.get(pokemon.riding.behaviour!!.key)
ridingBehaviourSettings = pokemon.riding.behaviour!!
ridingState = riding!!.createDefaultState(ridingBehaviourSettings!!)
}
/**
@@ -354,10 +357,11 @@ open class PokemonEntity(
}
var flyDistO = 0F
var isPokemonWalking = false
var isPokemonFlying = false
var tickSpawned = 0
init {
delegate.initialize(this)
delegate.changePokemon(pokemon)
@@ -482,6 +486,11 @@ open class PokemonEntity(
entityData.get(MOVING)
super.tick()
if (passengers.isNotEmpty()) {
ridingAnimationData.update(this)
}
flyDistO = flyDist
if (isBattling) {
@@ -1011,12 +1020,15 @@ open class PokemonEntity(
itemStack
)
if (player.isShiftKeyDown) {
val canRide = ifRidingAvailableSupply(false) { behaviour, settings, state ->
this.canRide(player) && seats.isNotEmpty() && behaviour.isActive(settings, state, this)
}
InteractPokemonUIPacket(
this.getUUID(),
canSitOnShoulder() && pokemon in player.party(),
!(pokemon.heldItemNoCopy().isEmpty && itemStack.isEmpty),
(!pokemon.cosmeticItem.isEmpty && itemStack.isEmpty) || cosmeticItemDefinition != null,
this.canRide(player) && pokemon.riding.canRide
canRide
).sendToPlayer(player)
} else {
// TODO #105
@@ -1236,6 +1248,7 @@ open class PokemonEntity(
else -> lang("held_item.replace", returned.displayName, this.pokemon.getDisplayName(), giving.displayName)
}
player.giveOrDropItemStack(returned, false)
player.sendSystemMessage(text)
this.level().playSoundServer(
position = this.position(),
@@ -1560,6 +1573,8 @@ open class PokemonEntity(
inp.z * g.toDouble() + inp.x * f.toDouble()
)
val diff = v.subtract(this.deltaMovement)
val inertia = ifRidingAvailableSupply(fallback = 0.5) { behaviour, settings, state ->
@@ -1919,7 +1934,7 @@ open class PokemonEntity(
// }
override fun onPassengerTurned(entityToUpdate: Entity) {
if (entityToUpdate !is LivingEntity) return
if (entityToUpdate !is LivingEntity) return
ifRidingAvailable { behaviour, settings, state ->
behaviour.clampPassengerRotation(settings, state, this, entityToUpdate)
}
@@ -1937,6 +1952,22 @@ open class PokemonEntity(
}
}
// When riding mimic RemotePlayers logic for rendering players at farther
// distances than usual. Otherwise the player may render when the pokemon
// entity is not, causing a floating player.
override fun shouldRenderAtSqrDistance(distance: Double): Boolean {
if (!passengers.isEmpty()) {
var d = (boundingBox.getSize() * 10.0)
if (d.isNaN()) {
d = 1.0
}
val scale = 64.0 * getViewScale()
return distance < d * scale * scale
}
return super.shouldRenderAtSqrDistance(distance)
}
override fun getControllingPassenger(): LivingEntity? {
val riders = this.passengers.filterIsInstance<LivingEntity>()
if (riders.isEmpty()) {
@@ -2100,4 +2131,4 @@ open class PokemonEntity(
override fun resolveEntityScan(): LivingEntity {
return this
}
}
}
@@ -8,10 +8,15 @@
package com.cobblemon.mod.common.entity.pokemon
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.entity.PokemonSender
import com.cobblemon.mod.common.api.entity.PokemonSideDelegate
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.api.pokemon.status.Statuses
@@ -21,6 +26,7 @@ import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.activestate.ActivePokemonState
import com.cobblemon.mod.common.pokemon.activestate.SentOutState
import com.cobblemon.mod.common.util.asUUID
import com.cobblemon.mod.common.util.getIsSubmerged
import com.cobblemon.mod.common.util.math.geometry.toRadians
import com.cobblemon.mod.common.util.playSoundServer
@@ -102,6 +108,32 @@ class PokemonServerDelegate : PokemonSideDelegate {
updateTrackedValues()
}
override fun addToStruct(struct: QueryStruct) {
super.addToStruct(struct)
if (entity.pokemon.isWild()) {
struct
.addFunction("attempt_wild_battle") { params ->
val opponentValue = params.get<MoValue>(0)
val opponent = if (opponentValue is ObjectValue<*>) {
opponentValue.obj as ServerPlayer
} else {
val paramString = opponentValue.asString()
val playerUUID = paramString.asUUID
if (playerUUID != null) {
entity.server!!.playerList.getPlayer(playerUUID) ?: return@addFunction DoubleValue.ZERO
} else {
entity.server!!.playerList.getPlayerByName(paramString) ?: return@addFunction DoubleValue.ZERO
}
}
// Need to wait to ensure any entity info gets grabbed properly before battle attempt.
return@addFunction entity.after(0.01F) {
DoubleValue(entity.forceBattle(opponent))
}
}
}
}
fun getBattle() = entity.battleId?.let(BattleRegistry::getBattle)
fun updateTrackedValues() {
@@ -256,6 +288,14 @@ class PokemonServerDelegate : PokemonSideDelegate {
}
}
fun doDeathDrops() {
if (entity.ownerUUID == null && entity.owner == null && entity.level().gameRules.getBoolean(CobblemonGameRules.DO_POKEMON_LOOT)) {
val heldItem = (entity as PokemonEntity?)?.pokemon?.heldItemNoCopy() ?: ItemStack.EMPTY
if (!heldItem.isEmpty) entity.spawnAtLocation(heldItem.item)
(entity.drops ?: entity.pokemon.form.drops).drop(entity, entity.level() as ServerLevel, entity.position(), entity.killer)
}
}
override fun updatePostDeath() {
// clear active effects before proceeding
val owner = entity.owner
@@ -268,6 +308,7 @@ class PokemonServerDelegate : PokemonSideDelegate {
if (entity.deathTime == 0) {
entity.effects.wipe()
entity.deathTime = 1
if (!Cobblemon.config.dropAfterDeathAnimation) doDeathDrops()
return
} else if (entity.effects.progress?.isDone == false) {
return
@@ -285,15 +326,8 @@ class PokemonServerDelegate : PokemonSideDelegate {
}
if (entity.deathTime == 60) {
if (entity.ownerUUID == null && entity.owner == null) {
entity.level().broadcastEntityEvent(entity, 60.toByte()) // Sends smoke effect
if(entity.level().gameRules.getBoolean(CobblemonGameRules.DO_POKEMON_LOOT)) {
val heldItem = (entity as PokemonEntity?)?.pokemon?.heldItemNoCopy() ?: ItemStack.EMPTY
if (!heldItem.isEmpty) entity.spawnAtLocation(heldItem.item)
(entity.drops ?: entity.pokemon.form.drops).drop(entity, entity.level() as ServerLevel, entity.position(), entity.killer)
}
}
entity.level().broadcastEntityEvent(entity, 60.toByte()) // Sends smoke effect
if (Cobblemon.config.dropAfterDeathAnimation) doDeathDrops()
entity.remove(Entity.RemovalReason.KILLED)
}
}
@@ -353,6 +353,18 @@ object CobblemonItemGroups {
entries.accept(CobblemonItems.LEEK_AND_POTATO_STEW)
entries.accept(CobblemonItems.BRAISED_VIVICHOKE)
entries.accept(CobblemonItems.VIVICHOKE_DIP)
entries.accept(CobblemonItems.TART_APPLE)
entries.accept(CobblemonItems.SWEET_APPLE)
entries.accept(CobblemonItems.SYRUPY_APPLE)
entries.accept(CobblemonItems.WHIPPED_DREAM)
entries.accept(CobblemonItems.STRAWBERRY_SWEET)
entries.accept(CobblemonItems.LOVE_SWEET)
entries.accept(CobblemonItems.BERRY_SWEET)
entries.accept(CobblemonItems.CLOVER_SWEET)
entries.accept(CobblemonItems.FLOWER_SWEET)
entries.accept(CobblemonItems.STAR_SWEET)
entries.accept(CobblemonItems.RIBBON_SWEET)
entries.accept(CobblemonItems.BERRY_JUICE)
entries.accept(CobblemonItems.REMEDY)
entries.accept(CobblemonItems.FINE_REMEDY)
@@ -475,6 +487,7 @@ object CobblemonItemGroups {
entries.accept(CobblemonItems.WHIPPED_DREAM)
entries.accept(CobblemonItems.TART_APPLE)
entries.accept(CobblemonItems.SWEET_APPLE)
entries.accept(CobblemonItems.SYRUPY_APPLE)
entries.accept(CobblemonItems.CRACKED_POT)
entries.accept(CobblemonItems.CHIPPED_POT)
entries.accept(CobblemonItems.MASTERPIECE_TEACUP)
@@ -644,9 +657,23 @@ object CobblemonItemGroups {
}
private fun foodInjections(injector: Injector) {
injector.putAfter(CobblemonItems.TART_APPLE, Items.ENCHANTED_GOLDEN_APPLE)
injector.putAfter(CobblemonItems.SWEET_APPLE, CobblemonItems.TART_APPLE)
injector.putAfter(CobblemonItems.SYRUPY_APPLE, CobblemonItems.SWEET_APPLE)
injector.putAfter(CobblemonItems.MEDICINAL_LEEK, Items.POISONOUS_POTATO)
injector.putAfter(CobblemonItems.ROASTED_LEEK, CobblemonItems.MEDICINAL_LEEK)
injector.putAfter(CobblemonItems.BRAISED_VIVICHOKE, CobblemonItems.ROASTED_LEEK)
injector.putAfter(CobblemonItems.WHIPPED_DREAM, Items.PUMPKIN_PIE)
injector.putAfter(CobblemonItems.STRAWBERRY_SWEET, CobblemonItems.WHIPPED_DREAM)
injector.putAfter(CobblemonItems.LOVE_SWEET, CobblemonItems.STRAWBERRY_SWEET)
injector.putAfter(CobblemonItems.BERRY_SWEET, CobblemonItems.LOVE_SWEET)
injector.putAfter(CobblemonItems.CLOVER_SWEET, CobblemonItems.BERRY_SWEET)
injector.putAfter(CobblemonItems.FLOWER_SWEET, CobblemonItems.CLOVER_SWEET)
injector.putAfter(CobblemonItems.STAR_SWEET, CobblemonItems.FLOWER_SWEET)
injector.putAfter(CobblemonItems.RIBBON_SWEET, CobblemonItems.STAR_SWEET)
injector.putAfter(CobblemonItems.LEEK_AND_POTATO_STEW, Items.RABBIT_STEW)
injector.putAfter(CobblemonItems.VIVICHOKE_DIP, CobblemonItems.LEEK_AND_POTATO_STEW)
}
@@ -10,10 +10,8 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.server
import net.minecraft.client.Minecraft
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
@@ -21,7 +19,7 @@ class ClientboundUpdateRidingStatePacket(
val entity: Int,
val behaviour: ResourceLocation,
val state: RidingBehaviourState? = null,
val data: RegistryFriendlyByteBuf? = null
val data: FriendlyByteBuf? = null
) : NetworkPacket<ClientboundUpdateRidingStatePacket> {
override val id = ID
@@ -37,7 +35,7 @@ class ClientboundUpdateRidingStatePacket(
fun decode(buffer: RegistryFriendlyByteBuf): ClientboundUpdateRidingStatePacket {
val entity = buffer.readInt()
val behaviour = buffer.readResourceLocation()
val state = RegistryFriendlyByteBuf(buffer.readBytes(buffer.readableBytes()), Minecraft.getInstance().player!!.registryAccess())
val state = FriendlyByteBuf(buffer.readBytes(buffer.readableBytes()))
return ClientboundUpdateRidingStatePacket(
entity = entity,
behaviour = behaviour,
@@ -48,6 +48,7 @@ class SpawnPokemonPacket(
var friendship: Int,
var freezeFrame: Float,
var passengers: IntArray,
var tickSpawned: Int,
vanillaSpawnPacket: ClientboundAddEntityPacket,
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
@@ -76,6 +77,7 @@ class SpawnPokemonPacket(
entity.entityData.get(PokemonEntity.FRIENDSHIP),
entity.entityData.get(PokemonEntity.FREEZE_FRAME),
entity.passengers.map { it.id }.toIntArray(),
entity.tickCount,
vanillaSpawnPacket
)
@@ -102,6 +104,7 @@ class SpawnPokemonPacket(
buffer.writeInt(this.friendship)
buffer.writeFloat(this.freezeFrame)
buffer.writeVarIntArray(this.passengers)
buffer.writeInt(this.tickSpawned)
}
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
@@ -136,6 +139,8 @@ class SpawnPokemonPacket(
val passenger = level.getEntity(it) ?: return@forEach
passenger.startRiding(entity)
}
entity.tickSpawned = this.tickSpawned
entity.delegate.updateAge(this.tickSpawned)
}
override fun checkType(entity: Entity): Boolean = entity is PokemonEntity
@@ -165,9 +170,10 @@ class SpawnPokemonPacket(
val friendship = buffer.readInt()
val freezeFrame = buffer.readFloat()
val passengers = buffer.readVarIntArray()
val tickSpawned = buffer.readInt()
val vanillaPacket = decodeVanillaPacket(buffer)
return SpawnPokemonPacket(ownerId, scaleModifier, speciesId, gender, shiny, formName, aspects, battleId, phasingTargetId, beamModeEmitter, platform, nickname, mark, labelLevel, poseType, unbattlable, hideLabel, caughtBall, spawnAngle, friendship, freezeFrame, passengers, vanillaPacket)
return SpawnPokemonPacket(ownerId, scaleModifier, speciesId, gender, shiny, formName, aspects, battleId, phasingTargetId, beamModeEmitter, platform, nickname, mark, labelLevel, poseType, unbattlable, hideLabel, caughtBall, spawnAngle, friendship, freezeFrame, passengers, tickSpawned, vanillaPacket)
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.platform.events
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
class ChangeDimensionEvent(val player: ServerPlayer)
class ChangeDimensionEvent(val player: ServerPlayer, val origin: ServerLevel?, val destination: ServerLevel?)
@@ -28,11 +28,14 @@ import net.minecraft.client.player.LocalPlayer
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.resources.ResourceLocation
import net.minecraft.sounds.SoundEvent
import net.minecraft.util.Mth.clamp
import kotlin.math.exp
import kotlin.math.ln
class PokedexUsageContext {
companion object {
const val ZOOM_STAGES = 10
const val ZOOM_MAX_STEP = 9F
const val ZOOM_TARGET_FOV = 10F // the FOV we get at max zoom (probably somewhat inaccurate, but irrelevant)
const val ZOOM_BASE_FOV = 80F // getting FOV from MC is easy, but pin it for consistent step count/zoom dist
const val BLOCK_LENGTH_PER_ZOOM_STAGE = 2
const val OPEN_SCANNER_BUFFER_TICKS = 5 // Open scanner interface if usage ticks are above this threshold
const val VIEW_INFO_BUFFER_TICKS = 10
@@ -59,6 +62,7 @@ class PokedexUsageContext {
var focusIntervals: Float = 0F
var innerRingRotation: Float = 0F
var zoomLevel: Float = 0F
var zoomModifier: Float = 1F
var newPokemonInfo: PokedexLearnedInformation = PokedexLearnedInformation.NONE
var type: PokedexType = PokedexType.RED
var availableInfoFrames: MutableList<Boolean?> = mutableListOf(null, null, null, null)
@@ -204,6 +208,7 @@ class PokedexUsageContext {
fun resetState(resetAnimationStates: Boolean = true) {
scanningGuiOpen = false
zoomLevel = 0F
zoomModifier = 1F
focusIntervals = 0F
resetFocusedPokemonState()
@@ -215,14 +220,22 @@ class PokedexUsageContext {
}
fun adjustZoom(verticalScrollAmount: Double) {
zoomLevel = clamp(zoomLevel + verticalScrollAmount.toFloat(), 0F, ZOOM_STAGES.toFloat())
if (zoomLevel > 0F && zoomLevel < ZOOM_STAGES.toFloat()) {
playSound(CobblemonSounds.POKEDEX_SCAN_ZOOM_INCREMENT)
}
if ((zoomLevel <= 0F && verticalScrollAmount < 0) || (zoomLevel >= ZOOM_MAX_STEP && verticalScrollAmount > 0))
return
playSound(CobblemonSounds.POKEDEX_SCAN_ZOOM_INCREMENT)
zoomLevel = (zoomLevel + verticalScrollAmount.toFloat()).coerceIn(0F, ZOOM_MAX_STEP)
innerRingRotation = (innerRingRotation + 15) % 360
val startLog = ln(ZOOM_BASE_FOV)
val targetLog = ln(ZOOM_TARGET_FOV)
val stepSize = (startLog - targetLog) / ZOOM_MAX_STEP
val currentZoomLog = startLog - (zoomLevel * stepSize)
val currentFov = exp(currentZoomLog)
zoomModifier = currentFov / ZOOM_BASE_FOV
}
// Higher multiplier = more zoomed out
fun getFovMultiplier() = 1 - (zoomLevel / ZOOM_STAGES)
// 1 = normal FOV; 0 = max zoom; this runs on render update, best to keep logic out of here
fun getFovMultiplier() = zoomModifier
fun playSound(soundEvent: SoundEvent) {
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(soundEvent, 1.0F))
@@ -20,7 +20,6 @@ import com.cobblemon.mod.common.util.battleLang
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.network.chat.Component
import net.minecraft.world.item.Items
import java.util.function.Function
/**
@@ -131,14 +130,7 @@ object CobblemonHeldItemManager : BaseCobblemonHeldItemManager() {
}
// if items aren't consumed, then we don't want to give them to wild pokemon (dupe)
if (this.giveItemEffect.contains(effectId) && (pokemon.actor is PlayerBattleActor || consumeHeldItems)) {
// extra check for item swapping abuse
// checks if the pokemon whose item is being taken away (wild pokemon) has its held item tampered with in any way
// this assumes its always moves causing the swaps
// I still think this is a bit brittle and can cause false positives, but for now this should do the trick I hope
var fromBattlePokemon = battle.majorBattleActions[pokemon.uuid]?.battlePokemon(2, battle)
if(showdownIdOf(fromBattlePokemon?.originalPokemon?.heldItem?.item ?: Items.AIR) == itemID) {
this.give(pokemon, itemID)
}
this.give(pokemon, itemID)
}
// allow players to steal wild held items
if (this.takeItemEffect.contains(effectId) && (pokemon.actor !is PlayerBattleActor || consumeHeldItems)) {
@@ -10,6 +10,12 @@ package com.cobblemon.mod.common.util.adapters
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.FallCompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.FallStrategy
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.JumpStrategy
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.RunStrategy
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
@@ -23,26 +29,42 @@ import java.lang.reflect.Type
* @author landonjw
*/
object RidingBehaviourSettingsAdapter : JsonDeserializer<RidingBehaviourSettings> {
val types: MutableMap<ResourceLocation, Class<out RidingBehaviourSettings>> = mutableMapOf(
BirdAirBehaviour.KEY to BirdAirSettings::class.java,
val types: MutableMap<ResourceLocation, Class<out RidingBehaviourSettings>> = mutableMapOf(BirdAirBehaviour.KEY to BirdAirSettings::class.java,
DolphinBehaviour.KEY to DolphinSettings::class.java,
FallToGlideCompositeBehaviour.KEY to FallToGlideCompositeSettings::class.java,
GenericLandBehaviour.KEY to GenericLandSettings::class.java,
GenericSwimBehaviour.KEY to GenericSwimSettings::class.java,
GliderAirBehaviour.KEY to GliderAirSettings::class.java,
HelicopterBehaviour.KEY to HelicopterSettings::class.java,
JetAirBehaviour.KEY to JetAirSettings::class.java,
JumpToFlightCompositeBehaviour.KEY to JumpToFlightCompositeSettings::class.java,
RunToJetCompositeBehaviour.KEY to RunToJetCompositeSettings::class.java,
SwimDashBehaviour.KEY to SwimDashSettings::class.java,
VehicleLandBehaviour.KEY to VehicleLandSettings::class.java
VehicleLandBehaviour.KEY to VehicleLandSettings::class.java,
HoverBehaviour.KEY to HoverSettings::class.java,
CompositeBehaviour.KEY to CompositeSettings::class.java,
/*
Strategy registration. if you do not register a strategy here, it will not be deserialized.
Register to CompositeSettings if you do not need to define a subclass.
*/
FallStrategy.key to FallCompositeSettings::class.java,
JumpStrategy.key to CompositeSettings::class.java,
RunStrategy.key to CompositeSettings::class.java,
)
override fun deserialize(element: JsonElement, type: Type, context: JsonDeserializationContext): RidingBehaviourSettings {
val root = element.asJsonObject
val key = root.get("key").asString
val behaviourType = types[key.asIdentifierDefaultingNamespace()] ?: throw IllegalArgumentException("Unknown controller: $key")
val settings: RidingBehaviourSettings = context.deserialize(element, behaviourType)
return settings
val keyIdentifier = key.asIdentifierDefaultingNamespace()
if (keyIdentifier == CompositeBehaviour.KEY) {
val strategy = root.get("transitionStrategy").asString
val strategyIdentifier = strategy.asIdentifierDefaultingNamespace()
val behaviourType = types[strategyIdentifier] ?: throw IllegalArgumentException("Unknown strategy for composite behaviour: $strategy")
val settings: RidingBehaviourSettings = context.deserialize(root, behaviourType)
return settings
}
else {
val behaviourType = types[keyIdentifier] ?: throw IllegalArgumentException("Unknown behaviour: $key")
val settings: RidingBehaviourSettings = context.deserialize(element, behaviourType)
return settings
}
}
}
@@ -0,0 +1,28 @@
{
"format_version": "1.8.0",
"animations": {
"animation.ride_test.sitting": {
"loop": true,
"bones": {
"body": {
"position": [0, -9, 0]
},
"torso": {
"rotation": [25, 0, 0]
},
"arm_right": {
"rotation": [0, 0, 22.5]
},
"arm_left": {
"rotation": [0, 0, -27.5]
},
"leg_right": {
"rotation": [-90, 20, 0]
},
"leg_left": {
"rotation": [-90, -20, 0]
}
}
}
}
}
@@ -2272,23 +2272,59 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.5833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.0417": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.375": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"5.875": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.5833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.375": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"5.875": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.5833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.0417": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.375": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"5.875": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.5833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.375": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"5.875": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
}
}
@@ -2553,15 +2589,27 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"1.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"3.6667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"1.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"3.6667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"1.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"3.6667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"1.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"3.6667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -8763,19 +8811,43 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.5": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.4583": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.5": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.4583": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.5": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.4583": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.5": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.4583": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
}
}
@@ -11221,23 +11293,59 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.4167": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"0.8333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.125": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.6667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.4167": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.125": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.6667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.4167": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"0.8333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.125": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.6667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.4167": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.125": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.6667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"locator_target": {
@@ -13529,19 +13637,43 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.2083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.7083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.2083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.7083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.2083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.7083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.2083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.7083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"locator_mouth": {
@@ -13740,14 +13872,20 @@
"position": {
"0.0": [-0.1, 0.1, 0],
"0.125": [-0.1, 0.1, 0],
"0.1667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0.1, 0],
"0.125": [0.1, 0.1, 0],
"0.1667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -14543,7 +14681,7 @@
"rotation": [0, -6, -15]
},
"wing_right_elbow": {
"rotation": [0, "-6", -15],
"rotation": [0, "-6+", -15],
"position": [0.45, 0.1, 0]
},
"wing_right_membrane": {
@@ -16036,7 +16174,7 @@
"animation_length": 4,
"bones": {
"body": {
"rotation": [22.5, 0, "math.sin(q.anim_time*90*1-90)*-0.5"],
"rotation": ["22.5 + q.riding.pitch(0)*-90", 0, "math.sin(q.anim_time*90*1-90)*-0.5"],
"position": ["math.cos(q.anim_time*90*1-60)*1", "12+math.cos((q.anim_time*90*2-60)+math.sin(q.anim_time*90*2)*20)*3", 0]
},
"torso": {
@@ -17357,6 +17495,14 @@
"locator_top": {
"position": [0, 13, 0]
}
},
"sound_effects": {
"1.125": {
"effect": "animation.leather.wing_flap.medium"
},
"3.1667": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.charizard.air_fly": {
@@ -18633,6 +18779,17 @@
},
"locator_top": {
"position": [0, -1, 0]
},
"locator_seat_1": {
"rotation": [-60, 0, 0]
}
},
"sound_effects": {
"1.0833": {
"effect": "animation.leather.wing_flap.medium"
},
"3.0833": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
@@ -18898,6 +19055,9 @@
},
"locator_top": {
"position": [0, -6, 0]
},
"locator_seat_1": {
"rotation": [-60, 0, 0]
}
}
},
@@ -19097,23 +19257,59 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.5833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.4167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.5833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"3.9167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"4.0833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.5833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.5833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.9167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"4.0833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.5833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.4167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.5833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"3.9167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"4.0833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.5833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.5833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.9167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"4.0833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
}
}
@@ -22458,7 +22654,10 @@
},
"0.5": [0.78, -10.13, 0.45],
"0.5417": [-0.45, -8.03, 0.45],
"0.5833": {"pre": [-0.45, -8.03, 0.45], "post": [-0.45, "-7.79+360", 0.45]},
"0.5833": {
"pre": [-0.45, -8.03, 0.45],
"post": [-0.45, "-7.79+360", 0.45]
},
"0.625": [-2.7, 355.37, 0.45],
"1.0": {
"pre": [-9.46, "10.71+360", 0.5],
@@ -26129,23 +26328,59 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.3333": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"1.625": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.8333": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.625": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.0833": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.3333": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"1.625": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.8333": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.625": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.3333": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"1.625": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.8333": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.625": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.0833": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.3333": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"1.625": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.8333": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.625": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"locator_root": {
@@ -29385,9 +29620,15 @@
"brow": {
"position": {
"0.9583": [0, 0, 0],
"1.1667": {"pre": [0, 0, 0], "post": [0, 0, -0.3]},
"1.1667": {
"pre": [0, 0, 0],
"post": [0, 0, -0.3]
},
"2.2917": [0, 0, -0.3],
"2.5417": {"pre": [0, 0, -0.3], "post": [0, 0, 0]}
"2.5417": {
"pre": [0, 0, -0.3],
"post": [0, 0, 0]
}
}
},
"jaw": {
@@ -29722,19 +29963,43 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.2083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.375": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.6667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.2083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.375": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.6667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.2083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.375": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.6667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.2083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.375": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.6667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"locator_root": {
@@ -29753,6 +30018,106 @@
}
}
},
"animation.charizard.ride_air_look": {
"loop": true,
"bones": {
"body": {
"rotation": ["q.riding.pitch_change(0)*-0", "q.riding.yaw_change(0)*-15", "q.riding.roll_change(0)*15"]
},
"neck": {
"rotation": ["math.clamp(q.riding.pitch_change(0),-0.5,1.0)*-20", 0, "q.riding.yaw_change(0)*7"]
},
"neck2": {
"rotation": ["math.clamp(q.riding.pitch_change(0),-0.5,1.0)*-12", 0, "q.riding.yaw_change(0)*12"]
},
"neck3": {
"rotation": ["q.riding.pitch_change(0)*-7", 0, "q.riding.yaw_change(0)*7"]
},
"neck4": {
"rotation": ["q.riding.pitch_change(0)*-7", 0, "q.riding.yaw_change(0)*7"]
},
"head_angle": {
"rotation": ["q.riding.pitch_change(0)*-7", 0, "q.riding.yaw_change(0)*7"]
},
"shoulder_right": {
"rotation": [0, "-12.5*q.riding.pitch_change(0)", "27.5*q.riding.yaw_change(0)"]
},
"arm_right": {
"rotation": [0, "15*q.riding.yaw_change(0)", 0]
},
"forearm_right": {
"rotation": [0, "15*q.riding.yaw_change(0)", "-12.5*q.riding.pitch_change(0)"]
},
"shoulder_left": {
"rotation": [0, "12.5*q.riding.pitch_change(0)", "27.5*q.riding.yaw_change(0)"]
},
"arm_left": {
"rotation": [0, "15*q.riding.yaw_change(0)", 0]
},
"forearm_left": {
"rotation": [0, "15*q.riding.yaw_change(0)", "12.5*q.riding.pitch_change(0)"]
},
"wing_right_base": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_right_bend": {
"rotation": ["10*q.riding.yaw_change(0)", "7.5*q.riding.pitch_change(0)", "10*q.riding.yaw_change(0)"]
},
"wing_right_mid": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_right_elbow": {
"rotation": ["-2.5*q.riding.pitch_change(0)", "5*q.riding.pitch_change(0)", 0]
},
"wing_left_base": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_left_bend": {
"rotation": ["-10*q.riding.yaw_change(0)", "-7.5*q.riding.pitch_change(0)", "-10*q.riding.yaw_change(0)"]
},
"wing_left_mid": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_left_elbow": {
"rotation": ["-2.5*q.riding.pitch_change(0)", "-(5*q.riding.pitch_change(0))", 0]
},
"tail": {
"rotation": ["q.riding.pitch_change(0)*7", 0, "q.riding.yaw_change(0)*-10"]
},
"tail2": {
"rotation": ["q.riding.pitch_change(0)*7", "q.riding.yaw_change(0)*15", 0]
},
"tail3": {
"rotation": ["q.riding.pitch_change(0)*7", "q.riding.yaw_change(0)*20", 0]
},
"tail4": {
"rotation": ["q.riding.pitch_change(0)*7", "q.riding.yaw_change(0)*20", 0]
},
"tail5": {
"rotation": ["q.riding.pitch_change(0)*8", "q.riding.yaw_change(0)*20", 0]
},
"leg_right": {
"rotation": ["-12.5*q.riding.pitch_change(0)", "q.riding.yaw_change(0)*20", 0],
"position": ["-1.5*q.riding.yaw_change(0)", 0, 0]
},
"knee_right": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
},
"foot_right": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
},
"leg_left": {
"rotation": ["-12.5*q.riding.pitch_change(0)", "q.riding.yaw_change(0)*20", 0],
"position": ["-1.5*q.riding.yaw_change(0)", 0, 0]
},
"knee_left": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
},
"foot_left": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
}
}
},
"animation.charizard.air_status": {
"animation_length": 3,
"bones": {
@@ -32994,19 +33359,43 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.2083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.2083": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.4583": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.2083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.2083": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.4583": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.2083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.2083": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.4583": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.2083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.2083": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.4583": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"locator_root": {
@@ -34432,14 +34821,20 @@
"position": {
"0.0": [-0.1, 0.1, 0],
"0.125": [-0.1, 0.1, 0],
"0.1667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0.1, 0],
"0.125": [0.1, 0.1, 0],
"0.1667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
"0.1667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
}
}
}
@@ -535,6 +535,11 @@
}
}
}
},
"sound_effects": {
"0.5": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.air_fly": {
@@ -710,6 +715,9 @@
},
"wing_open_right4": {
"rotation": [0, 0, "7.5+math.sin(q.anim_time*90*0.8-240)*-10+math.sin(q.anim_time*90*12-120)*0.4"]
},
"locator_seat1": {
"position": [0, 1.5, -4]
}
}
},
@@ -1566,6 +1574,11 @@
}
}
}
},
"sound_effects": {
"1.375": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.air_fly_quirk2": {
@@ -2721,6 +2734,14 @@
}
}
}
},
"sound_effects": {
"1.4583": {
"effect": "animation.plumage.wing_flap.medium"
},
"3.0833": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.blink": {
@@ -182,6 +182,14 @@
"rotation": [0, 0, 0]
}
}
},
"animation.eevee.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.eevee.cry"
}
}
}
}
}
@@ -225,6 +225,14 @@
"rotation": [-59.83045, -1.29256, -14.94548]
}
}
},
"animation.vaporeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.vaporeon.cry"
}
}
}
}
}
@@ -150,6 +150,14 @@
"rotation": [37.5, 37.5, 0]
}
}
},
"animation.jolteon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.jolteon.cry"
}
}
}
}
}
@@ -266,6 +266,14 @@
"rotation": [37.5, 27.5, 0]
}
}
},
"animation.flareon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.flareon.cry"
}
}
}
}
}
@@ -467,6 +467,7 @@
},
"animation.aerodactyl.air_idle": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"aerodactyl": {
"position": [0, 3, 0]
@@ -642,10 +643,16 @@
"right_wing_membrane": {
"rotation": [0, "0+math.sin(q.anim_time*90*3+90)*3", "0+math.sin(q.anim_time*90*3+90)*1.5"]
}
},
"sound_effects": {
"1.0833": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.aerodactyl.air_fly": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"aerodactyl": {
"position": [0, 3, 0]
@@ -827,6 +834,11 @@
"right_horn": {
"rotation": ["math.sin(q.anim_time*90*12-160)*2", 0, 0]
}
},
"sound_effects": {
"0.9583": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.aerodactyl.sleep": {
@@ -1237,6 +1237,20 @@
"rotation": ["-math.sin(q.anim_time*90*2-120)*4", 0, 0],
"position": [0, "7.8+math.sin(q.anim_time*90*2)*2", -5.6]
}
},
"sound_effects": {
"1.5": {
"effect": "animation.leather.wing_flap.medium"
},
"3.5": {
"effect": "animation.leather.wing_flap.medium"
},
"5.5": {
"effect": "animation.leather.wing_flap.medium"
},
"7.5": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.dragonite.water_idle": {
@@ -2053,6 +2067,89 @@
"effect": "pokemon.dragonite.cry"
}
}
},
"animation.dragonite.shock": {
"loop": true,
"bones": {
"pupil_left": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_left": {
"position": [0, -0.5, 0]
},
"pupil_right": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_right": {
"position": [0, -0.5, 0]
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"eye_left": {
"position": [0, 0, 0],
"scale": 1
},
"eye_shocked_left": {
"position": [0.25, 0, -0.26]
},
"eye_shocked_right": {
"position": [-0.125, 0, -0.18]
}
}
},
"animation.dragonite.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_shine_left": {
"position": [0, -1, 0]
},
"eye_shine_right": {
"position": [0, -1, 0]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.dragonite.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0.1, 0, -0.1]
},
"eye_sad_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.dragonite.happy": {
"loop": true,
"bones": {
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
},
"jaw": {
"rotation": [27.5, 0, 0]
}
}
},
"animation.dragonite.hurt": {
"loop": true,
"bones": {
"eyelid_recoil_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_recoil_right": {
"position": [-0.1, 0, -0.1]
}
}
}
}
}
@@ -188,6 +188,14 @@
"rotation": [12.5, 0, 0]
}
}
},
"animation.espeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.espeon.cry"
}
}
}
}
}
@@ -233,6 +233,14 @@
"rotation": [-20, 0, 0]
}
}
},
"animation.umbreon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.umbreon.cry"
}
}
}
}
}
@@ -2,257 +2,102 @@
"format_version": "1.8.0",
"animations": {
"animation.treecko.test": {
"animation_length": 1.2,
"loop": true,
"bones": {
"head": {
"rotation": [-2.5, 0, 0]
"rotation": [-10, 0, 0],
"position": [0, 0.1, -0.3]
},
"jaw": {
"rotation": [42.5, 0, 0]
"rotation": [32.5, 0, 0]
},
"tail": {
"rotation": [-45, 0, 0],
"position": [0, -0.5, 0]
},
"left_tail": {
"tail_left": {
"rotation": [10, 0, 2.5]
},
"left_tail2": {
"tail_left2": {
"rotation": [17.5, 0, 0]
},
"right_tail": {
"tail_right": {
"rotation": [10, 0, -2.5]
},
"right_tail2": {
"tail_right2": {
"rotation": [15, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [0, 0, -5]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, -57.5]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 20]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 45]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 20]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 45]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 20]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 45]
},
"right_upper_arm": {
"arm_right": {
"rotation": [0, 0, 5]
},
"torso": {
"rotation": [7.5, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [-5, 0, 0]
},
"neck": {
"rotation": [-5, 0, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, 57.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -20]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -45]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -20]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -45]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -20]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -45]
},
"left_upper_leg": {
"leg_left": {
"rotation": [1.18155, -9.91358, -2.38565]
},
"left_foot": {
"foot_left": {
"rotation": [-0.4165, -7.26605, 3.29302]
},
"right_upper_leg": {
"leg_right": {
"rotation": [1.18155, 9.91358, 2.38565]
},
"right_foot": {
"foot_right": {
"rotation": [-0.4165, 7.26605, -3.29302]
}
}
},
"animation.treecko.test2": {
"loop": true,
"bones": {
"torso": {
"rotation": [-4.73298, 2.77592, 27.09295]
},
"tail": {
"rotation": [-6.80313, 33.64286, -11.17316],
"position": [0.25, 0, 0]
},
"left_tail": {
"rotation": [15.32536, 9.84392, 1.79183]
},
"left_tail2": {
"rotation": [15.64835, 14.47267, 4.00563]
},
"right_tail": {
"rotation": [20.05865, 9.84795, 1.74036]
},
"right_tail2": {
"rotation": [17.62876, 9.658, 2.59914]
},
"upper_torso": {
"rotation": [12.06953, 5.56451, -12.40436]
},
"neck": {
"rotation": [3.59647, 22.86202, -3.90796]
},
"head": {
"rotation": [8.6876, -10.06991, 4.69965],
"position": [0, 0, -0.5]
},
"right_pupil": {
"position": [0, 0, -0.5]
},
"left_upper_arm": {
"rotation": [0, 22.5, -25],
"position": [0, 0, 0.25]
},
"left_lower_arm": {
"rotation": [0, 5, 0]
},
"left_hand": {
"rotation": [-17.87814, -19.86103, -49.99202],
"position": [-0.15, 0.05, 0]
},
"left_index_finger": {
"rotation": [0, 5, 20]
},
"left_index_finger2": {
"rotation": [0, 0, 45]
},
"left_pinky_finger": {
"rotation": [0, -5, 20]
},
"left_pinky_finger2": {
"rotation": [0, 0, 45]
},
"left_middle_finger": {
"rotation": [0, 0, 20]
},
"left_middle_finger2": {
"rotation": [0, 0, 45]
},
"right_upper_arm": {
"rotation": [27.9096, 1.08115, 23.32938]
},
"right_lower_arm": {
"rotation": [0, -10, 0]
},
"right_hand": {
"rotation": [8.98458, -4.04496, 42.82624],
"position": [0.15, 0.05, 0]
},
"right_index_finger": {
"rotation": [0, -15, -20]
},
"right_index_finger2": {
"rotation": [0, 0, -45]
},
"right_pinky_finger": {
"rotation": [0, 15, -20]
},
"right_pinky_finger2": {
"rotation": [0, 0, -45]
},
"right_middle_finger": {
"rotation": [0, 0, -20]
},
"right_middle_finger2": {
"rotation": [0, 0, -45]
},
"right_upper_leg": {
"rotation": [-118.81845, 9.91358, 2.38565],
"position": [0, 0.75, -1.25]
},
"right_foot": {
"rotation": [-11.96634, 26.73797, -15.04829]
},
"left_upper_leg": {
"rotation": [-2.91472, -22.08853, 21.08653]
},
"left_foot": {
"rotation": [65.81573, -6.16374, -15.44323]
},
"body": {
"position": [0, 0.75, 0]
},
"right_tail3": {
"rotation": [0, 0, 0]
},
"jaw": {
"rotation": [50, 0, 0]
},
"right_lower_leg": {
"rotation": [70.02991, 6.8466, -10.45577]
},
"right_foot2": {
"rotation": [12.5, 0, 0],
"position": [0, 0, 0.25]
},
"right_toes": {
"rotation": [17.5, 0, 0]
},
"left_lower_leg": {
"rotation": [16.93839, -4.46375, 14.33501]
},
"left_foot2": {
"rotation": [-40.67815, -9.54385, 8.11019]
},
"left_toes": {
"rotation": [-24.91643, -2.11089, -4.53359]
},
"left_pupil": {
"position": [0, 0, 0.5]
},
"right_inner_toe": {
"rotation": [25, -20, 0]
},
"right_outer_toe": {
"rotation": [22.5, 20, 0]
},
"right_middle_toe": {
"rotation": [15, 0, 0]
},
"left_inner_toe": {
"rotation": [-32.5, 0, 0]
},
"left_outer_toe": {
"rotation": [-25, 0, 0]
},
"left_middle_toe": {
"rotation": [-25, 0, 0]
}
}
},
"animation.treecko.ground_idle": {
"loop": true,
"bones": {
@@ -262,19 +107,19 @@
"tail": {
"rotation": [-45, 0, 0]
},
"left_tail": {
"tail_left": {
"rotation": [10, 0, 0]
},
"left_tail2": {
"tail_left2": {
"rotation": [15, 0, 0]
},
"right_tail": {
"tail_right": {
"rotation": [10, 0, 0]
},
"right_tail2": {
"tail_right2": {
"rotation": [15, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [-5, 0, 0]
},
"neck": {
@@ -283,95 +128,106 @@
"head": {
"rotation": [2.5, 0, 0]
},
"right_pupil": {
"pupil_right": {
"position": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [10.08453, -7.38542, 48.69038]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 42.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 22.5],
"position": [-0.15, 0.05, 0]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [6.94363, 7.64256, 14.02881]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 22.5]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [-4.01743, -1.75217, 14.46202]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 30]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 20]
},
"right_upper_arm": {
"arm_right": {
"rotation": [10.08453, 7.38542, -48.69038]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -42.5, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -22.5],
"position": [0.15, 0.05, 0]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [6.94363, -7.64256, -14.02881]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -22.5]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [-4.01743, 1.75217, -14.46202]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -30]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -12.5]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -20]
},
"right_upper_leg": {
"leg_right": {
"rotation": [1.18155, 9.91358, 2.38565]
},
"right_foot": {
"foot_right": {
"rotation": [-0.4165, 7.26605, -3.29302]
},
"left_upper_leg": {
"leg_left": {
"rotation": [1.18155, -9.91358, -2.38565]
},
"left_foot": {
"foot_left": {
"rotation": [-0.4165, -7.26605, 3.29302]
},
"stick": {
"rotation": [30, 45, 0],
"scale": 0.7
}
}
},
"animation.treecko.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"left_eyelid": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": {"pre": [0.1, 0, 0], "post": [0.1, 0, 0]},
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
},
"right_eyelid": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": {"pre": [-0.1, 0, 0], "post": [-0.1, 0, 0]},
"0.125": [-0.1, 0, 0],
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
}
}
},
@@ -422,25 +278,25 @@
"tail": {
"rotation": ["-42.5+math.sin(q.anim_time*90*8+0)*3", "math.sin(q.anim_time*90*4+60)*10", 0]
},
"left_tail": {
"tail_left": {
"rotation": ["10+math.sin(q.anim_time*90*8-25)*2", "0+math.sin(q.anim_time*90*4+30)*8", 0]
},
"left_tail2": {
"tail_left2": {
"rotation": ["15+math.sin(q.anim_time*90*8-55)*2", "0+math.sin(q.anim_time*90*4+0)*6", 0]
},
"left_tail3": {
"tail_left3": {
"rotation": ["0+math.sin(q.anim_time*90*8-85)*2", "0+math.sin(q.anim_time*90*4-30)*4", 0]
},
"right_tail": {
"tail_right": {
"rotation": ["10+math.sin(q.anim_time*90*8-35)*2", "0+math.sin(q.anim_time*90*4+30)*8", 0]
},
"right_tail2": {
"tail_right2": {
"rotation": ["15+math.sin(q.anim_time*90*8-65)*2", "0+math.sin(q.anim_time*90*4+0)*6", 0]
},
"right_tail3": {
"tail_right3": {
"rotation": ["0+math.sin(q.anim_time*90*8-95)*2", "0+math.sin(q.anim_time*90*4-30)*4", 0]
},
"upper_torso": {
"torso2": {
"rotation": ["-5+math.sin(q.anim_time*90*8+0)*1", "0+math.sin(q.anim_time*90*4+60+180)*5", "0+math.sin(q.anim_time*90*4+60)*3"]
},
"neck": {
@@ -449,66 +305,66 @@
"head": {
"rotation": ["2.5+math.sin(q.anim_time*90*8-60)*1.5", "0+math.sin(q.anim_time*90*4+0)*5", "0+math.sin(q.anim_time*90*4+0+180)*3"]
},
"right_pupil": {
"pupil_right": {
"position": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [10.08453, "-7.3854+math.sin(q.anim_time*90*4-90)*25", "48.6904+math.sin(q.anim_time*90*4+0)*2.5"]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, "42.5+math.sin(q.anim_time*90*4-120)*20", 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, "0+math.sin(q.anim_time*90*4-150)*2.5", "22.5+math.sin(q.anim_time*90*4-150)*5"],
"position": [-0.15, 0.05, 0]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [6.94363, 7.64256, 14.02881]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 22.5]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [-4.01743, -1.75217, 14.46202]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 30]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 20]
},
"right_upper_arm": {
"arm_right": {
"rotation": [10.08453, "7.3854+math.sin(q.anim_time*90*4-90)*25", "-48.6904+math.sin(q.anim_time*90*4+0)*2.5"]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, "-42.5+math.sin(q.anim_time*90*4-120)*20", 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, "0+math.sin(q.anim_time*90*4-150)*2.5", "-22.5+math.sin(q.anim_time*90*4-150)*5"],
"position": [0.15, 0.05, 0]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [6.94363, -7.64256, -14.02881]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -22.5]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [-4.01743, 1.75217, -14.46202]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -30]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -12.5]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -20]
},
"right_upper_leg": {
"leg_right": {
"rotation": {
"0.0": {
"post": [36.50677, 8.43184, 4.42536],
@@ -558,7 +414,7 @@
}
}
},
"right_lower_leg": {
"leg_right2": {
"rotation": {
"0.0": {
"post": [15, 0, 0],
@@ -586,7 +442,7 @@
}
}
},
"right_foot": {
"foot_right": {
"rotation": {
"0.0": {
"post": [24.37394, 0.4385, -6.40588],
@@ -614,7 +470,7 @@
}
}
},
"right_foot2": {
"foot_right2": {
"rotation": {
"0.0": {
"post": [-30, 0, 0],
@@ -652,7 +508,7 @@
}
}
},
"right_toes": {
"toes_right": {
"rotation": {
"0.0": {
"post": [-42.5, 0, 0],
@@ -690,7 +546,7 @@
}
}
},
"left_upper_leg": {
"leg_left": {
"rotation": {
"0.0": {
"post": [-61.31845, -9.91358, -2.38565],
@@ -740,7 +596,7 @@
}
}
},
"left_lower_leg": {
"leg_left2": {
"rotation": {
"0.0": {
"post": [47.5, 0, 0],
@@ -768,7 +624,7 @@
}
}
},
"left_foot": {
"foot_left": {
"rotation": {
"0.0": {
"post": [-30.4165, -7.26605, 3.29302],
@@ -796,7 +652,7 @@
}
}
},
"left_foot2": {
"foot_left2": {
"rotation": {
"0.0": {
"post": [12.5, 0, 0],
@@ -834,7 +690,7 @@
}
}
},
"left_toes": {
"toes_right2": {
"rotation": {
"0.0": {
"post": [15, 0, 0],
@@ -882,6 +738,265 @@
}
}
},
"animation.treecko.test2": {
"loop": true,
"bones": {
"torso": {
"rotation": [-4.73298, 2.77592, 27.09295]
},
"tail": {
"rotation": [-5.82738, 13.76109, -8.78252],
"position": [0.25, 0, 0]
},
"tail_left": {
"rotation": [17.07306, 24.25643, 6.31117]
},
"tail_left2": {
"rotation": [24.53554, -3.67372, -4.51152]
},
"tail_right": {
"rotation": [20.05865, 9.84795, 1.74036]
},
"tail_right2": {
"rotation": [25.12876, 9.658, 2.59914]
},
"torso2": {
"rotation": [7.06953, 5.56451, -12.40436],
"position": [0, 0, 0.5]
},
"neck": {
"rotation": [0.41092, 23.12473, -12.05132],
"position": [0, 0.5, 0]
},
"head": {
"rotation": [12.80178, -8.52421, -5.3105],
"position": [0, 0.5, -1]
},
"pupil_right": {
"position": [0, 0, -0.5]
},
"arm_left": {
"rotation": [9.29398, -6.81225, -20.04345],
"position": [0, 0.25, 1]
},
"arm_left2": {
"rotation": [0.65426, 4.95712, 7.52832]
},
"hand_left": {
"rotation": [-17.87814, -19.86103, -49.99202],
"position": [-0.15, 0.05, 0]
},
"finger_front_left": {
"rotation": [0, 5, 20]
},
"finger_front_left2": {
"rotation": [0, 0, 45]
},
"finger_back_left": {
"rotation": [0, -5, 20]
},
"finger_back_left2": {
"rotation": [0, 0, 45]
},
"finger_middle_left": {
"rotation": [0, 0, 20]
},
"finger_middle_left2": {
"rotation": [0, 0, 45]
},
"arm_right": {
"rotation": [28.39833, -11.25395, 25.21731],
"position": [0, 3, -3.25]
},
"arm_right2": {
"rotation": [0, -27.5, 0]
},
"hand_right": {
"rotation": [8.98458, -4.04496, 42.82624],
"position": [0.15, 0.05, 0]
},
"finger_front_right": {
"rotation": [24.55654, -22.88323, -18.35198]
},
"finger_front_right2": {
"rotation": [0, 0, -45]
},
"finger_back_right": {
"rotation": [24.23178, 6.06465, 25.68919]
},
"finger_back_right2": {
"rotation": [0, 0, -45]
},
"finger_middle_right": {
"rotation": [0, 0, 15]
},
"finger_middle_right2": {
"rotation": [0, 0, -45]
},
"leg_right": {
"rotation": [-156.31845, 9.91358, 2.38565],
"position": [0, 0.75, -2.25]
},
"foot_right": {
"rotation": [0.53366, 26.73797, -15.04829]
},
"leg_left": {
"rotation": [-2.91472, -22.08853, 21.08653],
"position": [0, -1, 0]
},
"foot_left": {
"rotation": [65.81573, -6.16374, -15.44323]
},
"body": {
"rotation": [0, 32.5, 0],
"position": [0, 1.75, 0]
},
"tail_right3": {
"rotation": [0, 0, 0]
},
"jaw": {
"rotation": [40, 0, 0]
},
"leg_right2": {
"rotation": [77.54738, -0.6465, -10.13344]
},
"foot_right2": {
"rotation": [12.5, 0, 0],
"position": [0, 0, 0.25]
},
"toes_right": {
"rotation": [17.5, 0, 0]
},
"leg_left2": {
"rotation": [16.93839, -4.46375, 14.33501]
},
"foot_left2": {
"rotation": [-35.67815, -9.54385, 8.11019]
},
"toes_right2": {
"rotation": [-24.91643, -2.11089, -4.53359]
},
"toe_inner_right": {
"rotation": [26.9673, -26.74473, -3.82626]
},
"toe_outer_right": {
"rotation": [22.5, 20, 0]
},
"toe_middle_right": {
"rotation": [15, 0, 0]
},
"toe_inner_left": {
"rotation": [-32.5, 0, 0]
},
"toe_outer_left": {
"rotation": [-25, 0, 0]
},
"toe_middle_left": {
"rotation": [-25, 0, 0]
},
"pupil_left": {
"position": [0, 0, 0.5]
},
"eye_shine_left": {
"position": [0, 0, 0.5]
}
}
},
"animation.treecko.eye_wide": {
"loop": true,
"bones": {
"eye_emote_right2": {
"scale": [1, 1.5, 1]
},
"eye_emote_left2": {
"scale": [1, 1.5, 1]
}
}
},
"animation.treecko.happy": {
"loop": true,
"bones": {
"jaw": {
"rotation": [20, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eye_left": {
"position": [-0.1, 0, 0]
},
"eyelid_happy_left": {
"position": [0.1, 0, 0]
},
"eyelid_happy_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.angry": {
"loop": true,
"bones": {
"eye_emote_right2": {
"position": [0.1, 0, 0]
},
"pupil_emote_right": {
"position": [0.1, 0, 0]
},
"eye_emote_left2": {
"position": [-0.1, 0, 0]
},
"pupil_emote_left": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.sad": {
"loop": true,
"bones": {
"eye_emote_right": {
"position": [0.1, 0, 0]
},
"eye_emote_left": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.shocked": {
"loop": true,
"bones": {
"jaw": {
"rotation": [20, 0, 0]
},
"pupil_right": {
"position": [0, 0, -0.2],
"scale": [1, 0.5, 0.7]
},
"pupil_left": {
"position": [0, 0, -0.2],
"scale": [1, 0.5, 0.7]
}
}
},
"animation.treecko.hurt": {
"loop": true,
"bones": {
"jaw": {
"rotation": [20, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eye_left": {
"position": [-0.1, 0, 0]
},
"eyelid_hurt_left": {
"position": [0.1, 0, 0]
},
"eyelid_hurt_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.cry": {
"animation_length": 1.2,
"sound_effects": {
@@ -7,7 +7,7 @@
"torso": {
"rotation": [10, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [5, 0, 0]
},
"neck": {
@@ -17,100 +17,122 @@
"rotation": [2.5, 0, 0]
},
"leaf7": {
"rotation": [12.5, 0, 0]
"rotation": [-5, 0, 0]
},
"jaw": {
"rotation": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [2.5, 7.5, 40]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 52.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [2.5, 0, 32.5]
},
"left_arm_leaves": {
"arm_leaves_left": {
"rotation": [-25.08377, -4.53051, 2.11751]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 10]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 27.5]
},
"left_tail": {
"tail_left": {
"rotation": [-10, 12.5, -2.5]
},
"left_tail2": {
"tail_left2": {
"rotation": [-15, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [0, -22.5, 0]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [0, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [0, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [0, 10, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [0, -10, 0]
},
"right_tail": {
"tail_right": {
"rotation": [-10, -12.5, 2.5]
},
"right_upper_leg": {
"leg_right": {
"rotation": [0, 22.5, 0]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [0, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [0, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [0, -10, 0]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [0, 10, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [2.5, -7.5, -40]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -52.5, 0]
},
"right_hand": {
"hand_right": {
"rotation": [2.5, 0, -32.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -10]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -27.5]
},
"right_arm_leaves": {
"arm_leaves_right": {
"rotation": [-25.08377, 4.53051, -2.11751]
},
"right_tail2": {
"tail_right2": {
"rotation": [-15, 0, 0]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 17.5]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 22.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -17.5]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -22.5]
},
"leaf": {
"rotation": [-50, 0, 0]
},
"leaf2": {
"rotation": [-35, 0, 0]
},
"leaf3": {
"rotation": [-22.5, 0, 0]
},
"leaf4": {
"rotation": [-25, 0, 0]
},
"leaf5": {
"rotation": [-25, 0, 0]
},
"leaf6": {
"rotation": [-7.5, 0, 0]
},
"stick": {
"rotation": [30, 40, 0],
"scale": 0.7
}
}
},
@@ -120,7 +142,7 @@
"torso": {
"rotation": [-5, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [2.5, 0, 0]
},
"neck": {
@@ -135,94 +157,94 @@
"jaw": {
"rotation": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-52.5, 5, 27.5]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 65, 0]
},
"left_hand": {
"hand_left": {
"rotation": [2.38443, -0.75155, 49.98436]
},
"left_arm_leaves": {
"arm_leaves_left": {
"rotation": [-10, -17.5, 0]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 2.5]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 5]
},
"left_tail": {
"tail_left": {
"rotation": [-15, 12.5, -2.5]
},
"left_tail2": {
"tail_left2": {
"rotation": [7.5, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [0, -22.5, 0]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [0, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [0, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [0, 10, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [0, -10, 0]
},
"right_tail": {
"tail_right": {
"rotation": [-15, -12.5, 2.5]
},
"right_upper_leg": {
"leg_right": {
"rotation": [0, 22.5, 0]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [0, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [0, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [0, -10, 0]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [0, 10, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-52.5, -5, -27.5]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -65, 0]
},
"right_hand": {
"hand_right": {
"rotation": [2.38443, 0.75155, -49.98436]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -2.5]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -5]
},
"right_arm_leaves": {
"arm_leaves_right": {
"rotation": [-10, 17.5, 0]
},
"right_tail2": {
"tail_right2": {
"rotation": [7.5, 0, 0]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 65]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 87.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -65]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -87.5]
}
}
@@ -233,7 +255,7 @@
"torso": {
"rotation": [45.38165, -3.51814, -7.08167]
},
"upper_torso": {
"torso2": {
"rotation": [-9.97857, 3.32943, 4.4913]
},
"neck": {
@@ -248,86 +270,86 @@
"jaw": {
"rotation": [42.5, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-12.58328, 9.94037, 39.45082]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 82.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [7.5, 0, 32.5]
},
"left_arm_leaves": {
"arm_leaves_left": {
"rotation": [-21.78282, -11.4487, 11.10461]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 10]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 22.5]
},
"left_tail": {
"tail_left": {
"rotation": [-17.99085, 11.53327, -4.85721]
},
"left_tail2": {
"tail_left2": {
"rotation": [-15, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [-37.5, -22.5, 0],
"position": [0.5, 0.5, -1]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [5, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [0, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [10, 10, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [20, -10, 0]
},
"right_tail": {
"tail_right": {
"rotation": [-28.32455, -16.15901, -4.25872]
},
"right_upper_leg": {
"leg_right": {
"rotation": [38, 7.5, 2.5],
"position": [0, -0.5, -0.5]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [5, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [27.5, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [-24.71447, -5.46269, -2.12052],
"position": [0, -0.1, 0.6]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [-24.71447, 5.46269, 2.12052],
"position": [0, -0.1, 0.6]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-14.26018, -29.40676, -34.54418]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -70, 0]
},
"right_hand": {
"hand_right": {
"rotation": [7.5, 0, -32.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -10]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"right_arm_leaves": {
"arm_leaves_right": {
"rotation": [-26.39218, 18.05776, -8.74472]
},
"right_tail2": {
"tail_right2": {
"rotation": [-15, 0, 0]
},
"body": {
@@ -345,76 +367,191 @@
"leaf6": {
"rotation": [5, 0, 0]
},
"left_back_toe": {
"toe_back_left": {
"rotation": [-5, 0, 0]
},
"right_back_toe": {
"toe_back_right": {
"rotation": [-10, 0, 0]
},
"left_outer_toe2": {
"toe_outer_left2": {
"rotation": [10, 0, 0]
},
"left_inner_toe2": {
"toe_inner_left2": {
"rotation": [10, 0, 0]
},
"right_inner_toe2": {
"toe_inner_right2": {
"rotation": [-45, 0, 0],
"position": [0, -0.55, 1.4]
},
"right_outer_toe2": {
"toe_outer_right2": {
"rotation": [-45, 0, 0],
"position": [0, -0.55, 1.4]
},
"left_leaf1": {
"arm_leaf_middle_left": {
"rotation": [15, 0, 0]
},
"left_leaf2": {
"arm_leaf_inner_left": {
"rotation": [5.76917, -1.99557, 14.05033]
},
"left_leaf3": {
"arm_leaf_outer_left": {
"rotation": [10, 0, 0]
},
"right_leaf1": {
"arm_leaf_middle_right": {
"rotation": [5, 0, 0]
},
"right_leaf2": {
"arm_leaf_inner_right": {
"rotation": [2.5, 0, 0]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 22.5]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 30]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -22.5]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -30]
}
}
},
"animation.grovyle.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eye_left": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
}
}
},
"animation.grovyle.happy": {
"loop": true,
"bones": {
"eye_left": {
"position": [-0.1, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eyelid_happy_left": {
"position": [0.1, 0, 0]
},
"eyelid_happy_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.grovyle.angry": {
"loop": true,
"bones": {
"eye_emote_right": {
"scale": [1, 1.5, 1]
},
"eye_brow_right": {
"position": [0, -0.3, 0]
},
"eye_brow_right2": {
"position": [0, 0.5, 0]
},
"eye_brow_left": {
"position": [0, -0.3, 0]
},
"eye_brow_left2": {
"position": [0, 0.5, 0]
},
"eye_emote_left": {
"scale": [1, 1.5, 1]
}
}
},
"animation.grovyle.sad": {
"loop": true,
"bones": {
"eye_brow_right": {
"position": [0, 0.5, 0]
},
"eye_brow_right2": {
"position": [0, -0.5, 0]
},
"eye_brow_left": {
"position": [0, 0.5, 0]
},
"eye_brow_left2": {
"position": [0, -0.5, 0]
}
}
},
"animation.grovyle.shocked": {
"loop": true,
"bones": {
"pupil_left": {
"position": [0, 0, -0.1],
"scale": [1, 0.5, 0.5]
},
"pupil_right": {
"position": [0, 0, -0.1],
"scale": [1, 0.5, 0.5]
},
"eye_emote_right": {
"position": [0, -0.5, 0],
"scale": [1, 2, 1]
},
"eye_brow_right": {
"position": [0, 0.3, 0]
},
"eye_brow_left": {
"position": [0, 0.3, 0]
},
"eye_emote_left": {
"position": [0, -0.5, 0],
"scale": [1, 2, 1]
}
}
},
"animation.grovyle.hurt": {
"loop": true,
"bones": {
"eye_left": {
"position": [-0.1, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eyelid_hurt_left": {
"position": [0.1, 0, 0]
},
"eyelid_hurt_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.grovyle.cry": {
"animation_length": 1.33333,
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.grovyle.cry"
@@ -7,7 +7,7 @@
"torso": {
"rotation": [17.5, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [-7.5, 0, 0]
},
"neck": {
@@ -16,37 +16,34 @@
"head": {
"rotation": [5, 0, 0]
},
"jaw": {
"rotation": [0, 0, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [0, 5, 0]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -50, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -27.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -20]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -15]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -25]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -47.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -50]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -40]
},
"right_upper_leg": {
"leg_right": {
"rotation": [0, 15, 0]
},
"tail": {
@@ -64,77 +61,81 @@
"tail5": {
"rotation": [7.5, 0, 0]
},
"right_shoulder": {
"shoulder_right": {
"rotation": [0, 0, -45]
},
"left_upper_leg": {
"leg_left": {
"rotation": [0, -15, 0]
},
"left_shoulder": {
"shoulder_left": {
"rotation": [0, 0, 45]
},
"left_upper_arm": {
"arm_left": {
"rotation": [0, -5, 0]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 50, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 27.5]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 20]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 50]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 15]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 40]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 25]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 47.5]
},
"right_arm_leaf_front_blade": {
"arm_leaf_front_blade_right": {
"scale": [1, 0, 1]
},
"right_arm_leaf_back_blade": {
"arm_leaf_back_blade_right": {
"scale": [1, 0, 1]
},
"left_arm_leaf_front_blade": {
"arm_leaf_front_blade_left": {
"scale": [1, 0, 1]
},
"left_arm_leaf_back_blade": {
"arm_leaf_back_blade_left": {
"scale": [1, 0, 1]
},
"left_top_leaves": {
"tail_leaves_top_left": {
"rotation": [2.5, 0, 0]
},
"left_bottom_leaves": {
"tail_leaves_bottom_left": {
"rotation": [0, -2.5, 0]
},
"left_top_leaves3": {
"tail_leaves_top_left3": {
"rotation": [-5, 0, 0]
},
"left_bottom_leaves3": {
"tail_leaves_bottom_left3": {
"rotation": [0, 5, 0]
},
"right_top_leaves": {
"tail_leaves_top_right": {
"rotation": [2.5, 0, 0]
},
"right_bottom_leaves": {
"tail_leaves_bottom_right": {
"rotation": [0, 2.5, 0]
},
"right_top_leaves3": {
"tail_leaves_top_right3": {
"rotation": [-5, 0, 0]
},
"right_bottom_leaves3": {
"tail_leaves_bottom_right3": {
"rotation": [0, -5, 0]
},
"stick": {
"rotation": [16, 40, 0],
"scale": 0.7
}
}
},
@@ -144,7 +145,7 @@
"torso": {
"rotation": [32.40109, 2.68407, -4.22005]
},
"upper_torso": {
"torso2": {
"rotation": [4.98107, -0.43523, 4.98107]
},
"neck": {
@@ -156,34 +157,34 @@
"jaw": {
"rotation": [45, 0, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-7.5, 2.5, 0]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -72.5, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -50]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -20]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -15]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -25]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -47.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -50]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -40]
},
"right_upper_leg": {
"leg_right": {
"rotation": [22.5, 15, 0],
"position": [0, 0.5, 0.5]
},
@@ -202,92 +203,92 @@
"tail5": {
"rotation": [12.79362, 12.19908, 2.74715]
},
"right_shoulder": {
"shoulder_right": {
"rotation": [-10.01754, 2.34914, -25.85553]
},
"left_upper_leg": {
"leg_left": {
"rotation": [-17.5, -15, 0],
"position": [0, 0, -0.5]
},
"left_shoulder": {
"shoulder_left": {
"rotation": [-11.9857, 23.12519, 20.20473]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-5, 10, 0]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 47.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 22.5]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 20]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 50]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 15]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 40]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 25]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 47.5]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [10, 0, 0]
},
"right_ankle": {
"leg_right3": {
"rotation": [0, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [10, 0, 0]
},
"right_middle_toe": {
"toe_middle_right": {
"rotation": [-42.5, 0, 0],
"position": [0, -0.5, 0.6]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [-43.11609, 4.07933, 4.44372],
"position": [0, -0.5, 0.6]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [-43.11609, -4.07933, -4.44372],
"position": [0, -0.5, 0.6]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [-5, 0, 0]
},
"left_ankle": {
"leg_left3": {
"rotation": [0, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [22.5, 0, 0]
},
"right_arm_leaf_front_blade": {
"arm_leaf_front_blade_right": {
"scale": [1, 0, 1]
},
"right_arm_leaf_back_blade": {
"arm_leaf_back_blade_right": {
"scale": [1, 0, 1]
},
"left_arm_leaf_front_blade": {
"arm_leaf_front_blade_left": {
"scale": [1, 0, 1]
},
"left_arm_leaf_back_blade": {
"arm_leaf_back_blade_left": {
"scale": [1, 0, 1]
},
"left_top_leaves": {
"tail_leaves_top_left": {
"rotation": [10, 0, 0]
},
"left_top_leaves2": {
"tail_leaves_top_left2": {
"rotation": [2.5, 0, 0]
},
"left_top_leaves3": {
"tail_leaves_top_left3": {
"rotation": [-7.5, 0, 0]
}
}
@@ -301,7 +302,7 @@
"torso": {
"rotation": [49.75757, -7.34759, 2.92368]
},
"upper_torso": {
"torso2": {
"rotation": [14.94548, 1.29256, -4.83045]
},
"neck": {
@@ -310,68 +311,68 @@
"head": {
"rotation": [-55.48448, 3.48051, -3.55608]
},
"right_shoulder": {
"shoulder_right": {
"rotation": [-58.62702, 15.46973, -8.28342],
"position": [0, -0.5, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-7.5, -1, -7.5]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -30, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -15]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -12.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -45]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, 22.5],
"position": [0.5, 0, 0]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -35]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -37.5]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -42.5]
},
"left_shoulder": {
"shoulder_left": {
"rotation": [-59.92127, -18.02575, 12.77165],
"position": [0, -0.5, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-7.5, 1, 7.5]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 42.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 15]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 12.5]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 45]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, -22.5],
"position": [-0.5, 0, 0]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 35]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 37.5]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 42.5]
},
"tail": {
@@ -390,97 +391,170 @@
"tail5": {
"rotation": [10.08453, -7.38542, -1.30962]
},
"right_upper_leg": {
"leg_right": {
"rotation": [-25.44458, 0.21572, -4.69162],
"position": [0, 0, -1]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [-5, -2.5, 0]
},
"right_ankle": {
"leg_right3": {
"rotation": [35, 0, 0],
"position": [0, 0, 0.6]
},
"right_foot": {
"foot_right": {
"rotation": [7.74222, 4.81281, 5.7589]
},
"right_middle_toe": {
"toe_middle_right": {
"rotation": [-12.5, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [-12.5, 0, 0]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [-12.5, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [32.71776, -4.77227, -5.22233],
"position": [0, 0, 1]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [4.96271, -0.86717, 4.92442]
},
"left_ankle": {
"leg_left3": {
"rotation": [42.5, 0, 0],
"position": [0, 0, 1]
},
"left_foot": {
"foot_left": {
"rotation": [85, 0, 0],
"position": [0, 0.35, 1.2]
},
"left_middle_toe": {
"toe_middle_left": {
"rotation": [5, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [10, 0, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [15, 0, 0]
},
"left_bottom_leaves": {
"tail_leaves_bottom_left": {
"rotation": [0, -5, 0]
},
"left_bottom_leaves3": {
"tail_leaves_bottom_left3": {
"rotation": [0, 5, 0]
},
"left_middle_toe2": {
"toe_middle_left2": {
"rotation": [17.5, 0, 0]
},
"left_inner_toe2": {
"toe_inner_left2": {
"rotation": [22.5, 0, 0]
},
"left_outer_toe2": {
"toe_outer_left2": {
"rotation": [15, 0, 0]
},
"right_top_leaves": {
"tail_leaves_top_right": {
"rotation": [2.5, 0, 0]
},
"right_top_leaves3": {
"tail_leaves_top_right3": {
"rotation": [-5, 0, 0]
}
}
},
"animation.sceptile.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"right_eyelid": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": {"pre": [-0.1, 0, 0], "post": [-0.1, 0, 0]},
"0.125": [-0.1, 0, 0],
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"left_eyelid": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": {"pre": [0.1, 0, 0], "post": [0.1, 0, 0]},
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
}
}
},
"animation.sceptile.hurt_or_happy": {
"loop": true,
"bones": {
"eyelid_hurt_right": {
"position": [-0.1, 0, 0]
},
"eyelid_hurt_left": {
"position": [0.1, 0, 0]
}
}
},
"animation.sceptile.angry": {
"loop": true,
"bones": {
"eye_brow_right": {
"position": [0, -0.4, 0]
},
"eye_brow_left": {
"position": [0, -0.4, 0]
},
"eye_brow_left2": {
"position": [0, 0.4, 0]
},
"eye_brow_right2": {
"position": [0, 0.4, 0]
}
}
},
"animation.sceptile.sad": {
"loop": true,
"bones": {
"pupil_right": {
"position": [0, 0.1, 0]
},
"pupil_left": {
"position": [0, 0.1, 0]
},
"eye_brow_right": {
"position": [0, 0.3, 0]
},
"eye_brow_left": {
"position": [0, 0.3, 0]
},
"eye_brow_left2": {
"position": [0, -0.4, 0]
},
"eye_brow_right2": {
"position": [0, -0.4, 0]
}
}
},
"animation.sceptile.shocked": {
"loop": true,
"bones": {
"jaw": {
"rotation": [35, 0, 0]
},
"pupil_right": {
"position": [0, 0.1, 0],
"scale": [1, 0.5, 0.5]
},
"pupil_left": {
"position": [0, 0.1, 0],
"scale": [1, 0.5, 0.5]
},
"eye_brow_right": {
"position": [0, 0.3, 0]
},
"eye_brow_left": {
"position": [0, 0.3, 0]
}
}
},
"animation.sceptile.cry": {
"animation_length": 1.33333,
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.sceptile.cry"
@@ -788,34 +788,30 @@
}
},
"animation.metagross.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eye_open_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_closed_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"eye_open_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_closed_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
}
@@ -972,12 +968,6 @@
"eye_closed_left": {
"position": [0, 0, -0.1]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"position": [0, 0, -0.1]
},
"leg_front_left": {
"rotation": [-20.94102, 8.42106, -69.05898]
},
@@ -1013,6 +1003,12 @@
},
"hand_back_right": {
"rotation": [0, 0, -15]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"position": [0, 0, -0.1]
}
}
},
@@ -1023,6 +1019,87 @@
"position": [0, 0, "-q.anim_time*90*0.2"]
}
}
},
"animation.metagross.shock": {
"loop": true,
"bones": {
"pupil_left": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_left": {
"position": [0, 0, 0.1]
},
"mouth": {
"position": [0, 0, -0.2]
},
"pupil_right": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_right": {
"position": [0, 0, 0.1]
}
}
},
"animation.metagross.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0, 0, -0.1]
},
"eye_angry_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.metagross.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0, 0, -0.1]
},
"eye_sad_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.metagross.happy": {
"loop": true,
"bones": {
"mouth": {
"position": [0, 0, -0.2]
},
"eye_open_left": {
"position": [0, 0, 0.1]
},
"eye_happy_left": {
"position": [0, 0, -0.1]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_happy_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.metagross.hurt": {
"loop": true,
"bones": {
"eye_open_left": {
"position": [0, 0, 0.1]
},
"eye_closed_left": {
"rotation": [0, 0, -20],
"position": [0, 0, -0.1]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"rotation": [0, 0, 20],
"position": [0, 0, -0.1]
}
}
}
}
}
@@ -5,7 +5,11 @@
"loop": true,
"bones": {
"body": {
"rotation": [0, "0 - Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5", "Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5"],
"rotation": [
"45*q.riding.velocity_forward(0)",
"0 - Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5",
"Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5 + 45*q.riding.velocity_right(0)"
],
"position": ["Math.Sin((q.anim_time * 180 * 0.5) * 1) * 1.5", "7+Math.Sin((q.anim_time * 90 * 0.5) * 1) * 1.5", 0]
},
"magnet_back_rotation": {
@@ -45,7 +49,11 @@
"loop": true,
"bones": {
"body": {
"rotation": [15, "0 - Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5", "Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5"],
"rotation": [
"2.5 + 45*q.riding.velocity_forward(0)",
"- Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5",
"Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5 - 45*q.riding.velocity_right(0)"
],
"position": ["Math.Sin((q.anim_time * 180 * 0.5) * 1) * 1.5", "7+Math.Sin((q.anim_time * 90 * 0.5) * 1) * 1.5", 0]
},
"magnet_back_rotation": {
@@ -266,45 +274,117 @@
"pupil_left": {
"position": {
"0.0": [0, 0, 0],
"0.5": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.5417": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.75": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"1.7917": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"2.0833": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.125": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
"0.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.5417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.75": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0833": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.125": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
}
},
"pupil_closed_left": {
"position": {
"0.0": [0, 0, 0],
"0.5": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.5417": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.75": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"1.7917": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"2.0833": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.125": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
"0.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.5417": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"1.75": {
"pre": [0, 0, -0.1],
"post": [0, 0, -0.1]
},
"1.7917": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"2.0833": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.125": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
}
},
"pupil_right": {
"position": {
"0.0": [0, 0, 0],
"0.2083": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"0.5": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"0.5417": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.9583": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.0": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
"0.2083": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.5": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0.1]
},
"0.5417": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"1.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.0": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
}
},
"pupil_closed_right": {
"position": {
"0.0": [0, 0, 0],
"0.2083": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"0.5": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"0.5417": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"1.9583": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.0": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
"0.2083": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.5": {
"pre": [0, 0, -0.1],
"post": [0, 0, -0.1]
},
"0.5417": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"1.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.0": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
}
}
},
@@ -470,6 +550,65 @@
}
}
},
"animation.magnezone.active": {
"loop": true,
"bones": {
"magnet_lights_left": {
"position": [0, 0, -0.1]
},
"magnet_lights_right": {
"position": [0, 0, -0.1]
},
"magnet_lights_back": {
"position": [0, 0, 0.1]
}
}
},
"animation.magnezone.shock": {
"loop": true,
"bones": {
"pupil_left": {
"scale": [0.7, 0.7, 1]
},
"pupil_right": {
"scale": [0.7, 0.7, 1]
}
}
},
"animation.magnezone.happy": {
"loop": true,
"bones": {
"pupil_left": {
"position": [0, 0, 0.1]
},
"pupil_right": {
"position": [0, 0, 0.1]
},
"pupil_happy_left": {
"position": [0, 0, -0.1]
},
"pupil_happy_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.magnezone.hurt": {
"loop": true,
"bones": {
"pupil_left": {
"position": [0, 0, 0.1]
},
"pupil_right": {
"position": [0, 0, 0.1]
},
"pupil_recoil_left": {
"position": [0, 0, -0.1]
},
"pupil_recoil_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.magnezone.cry": {
"animation_length": 1.2,
"sound_effects": {
@@ -159,6 +159,14 @@
"rotation": [-9.99762, -0.10901, 10.00238]
}
}
},
"animation.leafeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.leafeon.cry"
}
}
}
}
}
@@ -177,6 +177,14 @@
"rotation": [0, 0, -7.5]
}
}
},
"animation.glaceon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.glaceon.cry"
}
}
}
}
}
@@ -0,0 +1,427 @@
{
"format_version": "1.8.0",
"animations": {
"animation.druddigon.ground_idle": {
"loop": true,
"bones": {
"arm_right1": {
"rotation": [-19.84214, -10.30464, -25.48972]
},
"arm_right2": {
"rotation": [7.5, 0, -22.5]
},
"arm_right3": {
"rotation": [0, -40, 0]
},
"hand_right": {
"rotation": [0, -7.5, -12.5]
},
"finger_right1": {
"rotation": [0, 0, -10]
},
"claw_right1": {
"rotation": [0, 0, -22.5]
},
"jaw": {
"rotation": [0, 0, 0],
"position": [0, -0.27716, -0.11481]
},
"torso": {
"rotation": [-7.5, 0, 0]
},
"tail_1": {
"rotation": [10, 0, 0]
},
"chest": {
"rotation": [-7.5, 0, 0]
},
"leg_left1": {
"rotation": [-6.23088, -21.01584, -15.72279],
"position": [0, -0.5, 0]
},
"leg_left2": {
"rotation": [32.5, 0, 0]
},
"foot_left": {
"rotation": [-43.40659, -12.60837, 8.19252]
},
"toe_left2": {
"rotation": [0, 0, 10]
},
"toe_left3": {
"rotation": [0, 0, -10]
},
"leg_right1": {
"rotation": [-6.23088, 21.01584, 15.72279],
"position": [0, -0.5, 0]
},
"leg_right2": {
"rotation": [32.5, 0, 0]
},
"foot_right": {
"rotation": [-43.40659, 12.60837, -8.19252]
},
"toe_right2": {
"rotation": [0, 0, -10]
},
"toe_right3": {
"rotation": [0, 0, 10]
},
"finger_right2": {
"rotation": [10, 37.5, 0]
},
"claw_right2": {
"rotation": [22.5, 0, 0]
},
"finger_right3": {
"rotation": [-5, -37.5, 0]
},
"claw_right3": {
"rotation": [-22.5, 0, 0]
},
"arm_left1": {
"rotation": [-19.84214, 10.30464, 25.48972]
},
"arm_left2": {
"rotation": [7.5, 0, 22.5]
},
"arm_left3": {
"rotation": [0, 40, 0]
},
"hand_left": {
"rotation": [0, 7.5, 12.5]
},
"finger_left1": {
"rotation": [0, 0, 10]
},
"claw_left1": {
"rotation": [0, 0, 22.5]
},
"finger_left2": {
"rotation": [10, -37.5, 0]
},
"claw_left2": {
"rotation": [22.5, 0, 0]
},
"finger_left3": {
"rotation": [-5, 37.5, 0]
},
"claw_left3": {
"rotation": [-22.5, 0, 0]
}
}
},
"animation.druddigon.battle_idle": {
"loop": true,
"bones": {
"arm_right1": {
"rotation": [-35.0999, -18.72795, -13.41336]
},
"arm_right2": {
"rotation": [1.0804, -5.1849, -12.8416]
},
"arm_right3": {
"rotation": [-29.5083, -47.382, -4.0162]
},
"hand_right": {
"rotation": [0, -7.5, -12.5]
},
"finger_right1": {
"rotation": [0, 0, -10]
},
"claw_right1": {
"rotation": [0, 0, -22.5]
},
"finger_right2": {
"rotation": [15, 40, 0]
},
"claw_right2": {
"rotation": [22.5, 0, 0]
},
"body": {
"rotation": [0, -12.5, 0],
"position": [0, 2, -0.6]
},
"torso": {
"rotation": [9.9863, 0.22463, 0.3039],
"position": [0, -1, 1]
},
"chest": {
"rotation": [-10.08226, 3.37738, -3.68895]
},
"wing_left": {
"rotation": [-7.5, 0, 0]
},
"neck": {
"rotation": [12.48609, 1.84353, -1.68884],
"position": [0, 0, -0.2]
},
"neck_mouth_closed": {
"scale": 0
},
"head": {
"rotation": [-22.54365, 1.71046, -4.69895]
},
"jaw": {
"rotation": [20, 0, 0],
"position": [0, -0.47716, -0.11481]
},
"leg_left1": {
"rotation": [1.06967, -28.21899, -16.6831]
},
"leg_left2": {
"rotation": [35, 0, 0]
},
"foot_left": {
"rotation": [-8.00865, -10.6666, 5.52624]
},
"toe_left1": {
"rotation": [-42.60882, -3.68425, 3.38262]
},
"toe_left3": {
"rotation": [-30.96089, -12.57966, -9.31627]
},
"toe_left2": {
"rotation": [-37.82102, 5.54652, 13.22471]
},
"toe_claw_left2": {
"rotation": [-5, 0, 0]
},
"toe_claw_left3": {
"rotation": [-10, 0, 0]
},
"leg_right1": {
"rotation": [-1.23088, 21.01584, 15.72279]
},
"leg_right2": {
"rotation": [35, 0, 0]
},
"foot_right": {
"rotation": [-8.00865, 10.6666, -5.52624]
},
"toe_right1": {
"rotation": [-42.60882, 3.68425, -3.38262]
},
"toe_right2": {
"rotation": [-37.82102, -5.54652, -13.22471]
},
"toe_claw_right2": {
"rotation": [-5, 0, 0]
},
"toe_right3": {
"rotation": [-30.96089, 12.57966, 9.31627]
},
"toe_claw_right3": {
"rotation": [-10, 0, 0]
},
"head_hidden": {
"scale": 0
},
"wing_right": {
"rotation": [-6.76783, 4.83809, -1.4594]
},
"tail_3": {
"rotation": [2.5, 0, 0]
},
"tail_4": {
"rotation": [10, 0, 0]
},
"wing_left2": {
"rotation": [0, 7.5, 0]
},
"finger_right3": {
"rotation": [-7.5, -40, 0]
},
"claw_right3": {
"rotation": [-22.5, 0, 0]
},
"arm_left1": {
"rotation": [-9.21772, 22.54829, 25.90265]
},
"arm_left2": {
"rotation": [1.0804, 5.1849, 12.8416]
},
"arm_left3": {
"rotation": [-40.89335, 59.21695, -14.63464]
},
"hand_left": {
"rotation": [0, 7.5, 12.5]
},
"finger_left1": {
"rotation": [0, 0, 25]
},
"claw_left1": {
"rotation": [0, 0, 97.5],
"position": [0, -1.8, 0]
},
"finger_left2": {
"rotation": [10.07885, -31.4612, 2.60512]
},
"claw_left2": {
"rotation": [100, 0, 0],
"position": [0, -1.8, 0]
},
"finger_left3": {
"rotation": [-20.94706, 24.49001, 0.53086]
},
"claw_left3": {
"rotation": [-90, 0, 0],
"position": [0, -2, 0]
}
}
},
"animation.druddigon.mouth_test": {
"loop": true,
"bones": {
"jaw": {
"rotation": [22.5, 0, 0],
"position": [0, -1, -0.5]
},
"neck_mouth_closed": {
"scale": 0
}
}
},
"animation.druddigon.new": {
"loop": true,
"bones": {
"head": {
"rotation": [-12.5, 0, 0]
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"head_hidden": {
"scale": 0
}
}
},
"animation.druddigon.angry": {
"loop": true
},
"animation.druddigon.sad": {
"loop": true,
"bones": {
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"eyelid_sad_left": {
"position": [0.1, 0, 0]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
},
"eyelid_sad_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.druddigon.unamused": {
"loop": true,
"bones": {
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"eyelid_unamused_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
},
"eyelid_unamused_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.druddigon.happy": {
"loop": true,
"bones": {
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.druddigon.surpised": {
"loop": true,
"bones": {
"neck_mouth_closed": {
"scale": 0
},
"pupil_left": {
"scale": [1, 0.7, 0.7]
},
"head_hidden": {
"scale": 0
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"pupil_right": {
"scale": [1, 0.7, 0.7]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
}
}
},
"animation.druddigon.rage": {
"loop": true,
"bones": {
"neck_mouth_closed": {
"scale": 0
},
"pupil_left": {
"scale": [1, 0.7, 0.7]
},
"head_hidden": {
"scale": 0
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"eyelid_angry_left": {
"position": [0, 0.4, 0]
},
"pupil_right": {
"scale": [1, 0.7, 0.7]
},
"eyelid_angry_right": {
"position": [0, 0.4, 0]
}
}
},
"animation.druddigon.hold_item": {
"loop": true,
"bones": {
"claw_right1": {
"rotation": [0, 0, -67.5],
"position": [0, -2, 0]
},
"finger_right2": {
"rotation": [20.11852, -67.56738, 9.02949],
"position": [0.6, -0.3, 1.1]
},
"claw_right2": {
"rotation": [82.5, 0, 0],
"position": [0, -2, 0]
},
"claw_right3": {
"rotation": [-70, 0, 0],
"position": [0, -2, 0]
}
}
}
}
}
@@ -4,112 +4,36 @@
"animation.braixen.ground_idle": {
"loop": true,
"bones": {
"torso_bottom": {
"rotation": ["-math.sin(q.anim_time*90*2.5-45)*0.75", 0, 0]
},
"neck": {
"rotation": ["10-math.sin(q.anim_time*90*2.5)*2", 0, 0]
},
"head": {
"rotation": ["2.5+math.sin(q.anim_time*90*2.5+45)*2", 0, 0]
},
"ear_ruff_right": {
"rotation": [0, 5, "-1-math.sin(q.anim_time*90*2.5+45)*1"]
},
"ear_ruff_right2": {
"rotation": [0, 10, "-math.sin(q.anim_time*90*2.5)*1"]
},
"ear_ruff_right3": {
"rotation": [0, 10, "-math.sin(q.anim_time*90*2.5-45)*1"]
},
"ear_ruff_left": {
"rotation": [0, -2.5, "1+math.sin(q.anim_time*90*2.5+45)*1"]
},
"ear_ruff_left2": {
"rotation": [0, -10, "math.sin(q.anim_time*90*2.5)*1"]
},
"ear_ruff_left3": {
"rotation": [0, -10, "math.sin(q.anim_time*90*2.5-45)*1"]
},
"arm_right": {
"rotation": [-1.56101, "12.3977-math.sin(q.anim_time*90*2.5+45)", -55.15982]
},
"arm_right2": {
"rotation": [-3.88714, -27.24513, 8.44236]
},
"arm_left": {
"rotation": [-1.465, "-12.404+math.sin(q.anim_time*90*2.5+45)*2", 55.14094]
},
"arm_left2": {
"rotation": [-6.31274, 31.94715, -11.80868]
},
"tail": {
"rotation": ["5+math.sin(q.anim_time*90*2.5)*2", "math.sin(q.anim_time*90*1.25-90)*4", "math.sin(q.anim_time*90*1.25-90)*2"],
"position": [0, 0, 0.5]
},
"stick_tail": {
"rotation": [0, 0, "-math.sin(q.anim_time*90*1.25-45)*4"]
},
"tail2": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1.25-45)*4"]
},
"tail3": {
"rotation": ["math.sin(q.anim_time*90*2.5-90)*2", 0, 0]
},
"tail4": {
"rotation": ["math.sin(q.anim_time*90*2.5-135)*2", 0, 0]
},
"finger_index_right": {
"rotation": [0, 0, -15]
},
"finger_middle_right": {
"rotation": [0, 0, -10]
},
"finger_ring_right": {
"rotation": [0, 0, -5]
},
"finger_index_left": {
"rotation": [0, 0, 15]
},
"finger_middle_left": {
"rotation": [0, 0, 10]
},
"finger_ring_left": {
"rotation": [0, 0, 5]
"torso": {
"rotation": [2.5, 0, 0]
},
"waist": {
"rotation": [-5, 0, 0]
},
"chest": {
"rotation": [2.5, 0, 0]
},
"arm_left": {
"rotation": [0, 7.5, 70]
},
"arm_left2": {
"rotation": [-5, 37.5, -2.5]
},
"hand_left": {
"rotation": [0, 0, -7.5]
"rotation": [57.5, -10, 7.5]
},
"finger_front_left": {
"rotation": [0, 0, 25]
"neck": {
"rotation": [-5, 0, 0]
},
"finger_back_left": {
"rotation": [0, 0, 22.5]
"head": {
"rotation": [12.5, 0, 0]
},
"hand_right": {
"rotation": [0, 0, 7.5]
},
"finger_front_right": {
"rotation": [0, 0, -25]
},
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"stick_hand": {
"scale": 0
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_shock_right": {
"scale": 0
},
"skirt_front2": {
"tail": {
"rotation": [5, 0, 0]
},
"stick_tail": {
"rotation": [-5, 0, 0]
},
"leg_left": {
"rotation": [0.88045, -9.96156, -5.07673]
},
@@ -125,8 +49,78 @@
"leg_right3": {
"rotation": [0.00039, 5.00185, -5.99069]
},
"finger_front_left": {
"rotation": [9.99527, 9.84653, 30.20756]
},
"finger_back_left": {
"rotation": [-4.26175, -9.05478, 25.33761]
},
"finger_middle_left": {
"rotation": [0, 0, 27.5]
},
"arm_right": {
"rotation": [65, 22.5, -45],
"position": [0, 0, 0.5]
},
"arm_right2": {
"rotation": [-15, -82.5, 15]
},
"hand_right": {
"rotation": [-10, -22.5, 70]
},
"finger_front_right": {
"rotation": [9.99527, -9.84653, -30.20756]
},
"finger_middle_right": {
"rotation": [0, 0, -27.5]
},
"finger_back_right": {
"rotation": [-4.26175, 9.05478, -25.33761]
},
"ear_ruff_left2": {
"rotation": [0, -7.5, 0]
},
"ear_ruff_left3": {
"rotation": [0, -7.5, 0]
},
"ear_ruff_left4": {
"rotation": [0, -7.5, 0]
},
"skirt_front2": {
"rotation": [-2.5, 0, 0]
},
"foot_right": {
"rotation": [1, 0, 0]
},
"ear_ruff_left": {
"rotation": [0, -7.5, 0]
},
"ear_ruff_right": {
"rotation": [0, 7.5, 0]
},
"ear_ruff_right2": {
"rotation": [0, 7.5, 0]
},
"ear_ruff_right3": {
"rotation": [0, 7.5, 0]
},
"ear_ruff_right4": {
"rotation": [0, 7.5, 0]
},
"skirt_front_left": {
"rotation": [0, 0, 10]
},
"skirt_front_right": {
"rotation": [0, 0, -10]
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_shock_right": {
"scale": 0
},
"wand": {
"scale": 0
}
}
},
@@ -134,13 +128,14 @@
"loop": true,
"bones": {
"body": {
"rotation": [0, -52.5, 0],
"position": [-0.5, -2.05, 0]
},
"torso": {
"rotation": [15, -10, 0]
},
"waist": {
"rotation": [5, 0, 0]
"rotation": [-2.5, -2.5, 0]
},
"chest": {
"rotation": [-5, 2.5, 0]
@@ -167,10 +162,10 @@
"rotation": [0, -10, 0]
},
"arm_right": {
"rotation": [-35.09473, -47.42923, -40.56425]
"rotation": [-60.09473, -14.92923, -20.56425]
},
"arm_right2": {
"rotation": [0, -40, 0]
"rotation": [0, -45, 0]
},
"hand_right": {
"rotation": [0, 27.5, 15]
@@ -185,10 +180,10 @@
"rotation": [0, 0, -77.5]
},
"neck": {
"rotation": [0, 5, 0]
"rotation": [0, 32.5, -7.5]
},
"head": {
"rotation": [-10, 0, 0]
"rotation": [-7.5, 20, -5]
},
"ear_ruff_left2": {
"rotation": [0, -12.5, 0]
@@ -221,28 +216,32 @@
"scale": 0
},
"leg_left": {
"rotation": [5.38152, -19.291, -15.91527]
"rotation": [-0.5, -35, -26],
"position": [1, 0, 0]
},
"leg_left2": {
"rotation": [25, 0, 0]
"rotation": [10, 0, 0]
},
"leg_left3": {
"rotation": [-16.28567, 14.26008, -10.25103]
"rotation": [-22.5, 0, 0]
},
"foot_left": {
"rotation": [-12.32417, 1.61888, 12.39638]
"rotation": [29.78634, -18.01295, 11.28749],
"position": [0, -0.5, 0]
},
"leg_right": {
"rotation": [-27.5, 0, 0]
"rotation": [-7.80674, 36.44232, 19.22515],
"position": [-1, -0.75, -0.75]
},
"leg_right2": {
"rotation": [27.25489, -5.05904, 5.54401]
"rotation": [29.75489, -5.05904, 8.04401]
},
"leg_right3": {
"rotation": [-25, 0, 0]
"rotation": [-30.5, -2, -1]
},
"foot_right": {
"rotation": [24.78729, 3.74196, -6.50446]
"rotation": [22.5, 20, -10],
"position": [0, -0.5, 0]
},
"ear_ruff_right2": {
"rotation": [0, 12.5, 0]
@@ -253,24 +252,111 @@
"ear_ruff_right4": {
"rotation": [0, 17.5, 0]
},
"stick_hand": {
"rotation": [90, 10, 0],
"position": [6.5, -1, -0.5]
},
"skirt_front_left": {
"rotation": [0, 0, 7.5]
},
"skirt_front_right": {
"rotation": [0, 0, -2.5]
},
"fire": {
"rotation": [-7.15656, 2.24944, 17.35932]
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_shock_right": {
"scale": 0
},
"skirt": {
"rotation": [-5, 0, 0]
},
"body_wand": {
"rotation": [0, -52.5, 0],
"position": [-0.5, -2.05, 0]
},
"torso_wand": {
"rotation": [15, -10, 0]
},
"waist_wand": {
"rotation": [-2.5, -2.5, 0]
},
"chest_wand": {
"rotation": [-5, 2.5, 0]
},
"arm_wand": {
"rotation": [-60.09473, -14.92923, -20.56425]
},
"arm2_wand": {
"rotation": [0, -45, 0]
},
"hand_wand": {
"rotation": [0, 27.5, 15]
},
"wand": {
"rotation": [90, 10, 0],
"position": [6.5, -1, -0.5]
}
}
},
"animation.braixen.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": {"pre": [0.1, 0, -0.1], "post": [0.1, 0, -0.1]},
"0.1667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.125": {"pre": [-0.1, 0, -0.1], "post": [-0.1, 0, -0.1]},
"0.1667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
}
}
},
"animation.braixen.cry": {
"animation_length": 1,
"bones": {
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [-2.05, 0, 0],
"0.0833": [-2.7, 0, 0],
"0.1667": [4, 0, 0],
"0.2083": [3.72, 0, 0],
"0.375": [-2.38, 0, 0],
"0.4167": [-2.7, 0, 0],
"0.5": [-2.4, 0, 0],
"0.6667": [-0.3, 0, 0],
"0.75": [0, 0, 0]
}
},
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [27.2, 0, 0],
"0.0833": [30, 0, 0],
"0.1667": [19, 0, 0],
"0.2083": [17.65, 0, 0],
"0.3333": [57.56, 0, 0],
"0.375": [60, 0, 0],
"0.4167": [56.99, 0, 0],
"0.7083": [4.23, 0, 0],
"0.7917": [0, 0, 0]
}
},
"fangs": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.5, 0],
"0.625": [0, -0.5, 0],
"0.6667": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.braixen.cry"
}
}
},
@@ -392,7 +478,7 @@
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"stick_hand": {
"wand": {
"scale": 0
},
"ear_ruff_shock_left": {
@@ -408,198 +494,6 @@
"rotation": [0, -12.5, 0]
}
}
},
"animation.braixen.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": [0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.125": [-0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.braixen.cry": {
"animation_length": 1,
"bones": {
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [-2.05, 0, 0],
"0.0833": [-2.7, 0, 0],
"0.1667": [4, 0, 0],
"0.2083": [3.72, 0, 0],
"0.375": [-2.38, 0, 0],
"0.4167": [-2.7, 0, 0],
"0.5": [-2.4, 0, 0],
"0.6667": [-0.3, 0, 0],
"0.75": [0, 0, 0]
}
},
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [27.2, 0, 0],
"0.0833": [30, 0, 0],
"0.1667": [19, 0, 0],
"0.2083": [17.65, 0, 0],
"0.3333": [57.56, 0, 0],
"0.375": [60, 0, 0],
"0.4167": [56.99, 0, 0],
"0.7083": [4.23, 0, 0],
"0.7917": [0, 0, 0]
}
},
"fangs": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.5, 0],
"0.625": [0, -0.5, 0],
"0.6667": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.braixen.cry"
}
}
},
"animation.braixen.surprise_hair": {
"loop": true,
"bones": {
"ear_ruff_left": {
"rotation": [0, 0, -10]
},
"ear_ruff_left2": {
"rotation": [0, 0, 10]
},
"ear_ruff_side_left": {
"rotation": [3.57152, 21.79524, -14.03271]
},
"ear_ruff_left3": {
"rotation": [0, 0, -2.5]
},
"ear_ruff_left4": {
"rotation": [0, 0, -12.5]
},
"ear_ruff_right": {
"rotation": [0, 0, 10]
},
"ear_ruff_right2": {
"rotation": [0, 0, -10]
},
"ear_ruff_side_right": {
"rotation": [3.57152, -21.79524, 14.03271]
},
"ear_ruff_right3": {
"rotation": [0, 0, 2.5]
},
"ear_ruff_right4": {
"rotation": [0, 0, 12.5]
},
"ear_ruff_shock_left": {
"rotation": [0, 0, 2.5]
},
"ear_ruff_shock_left2": {
"rotation": [0, 0, -12.5]
},
"ear_ruff_shock_right": {
"rotation": [0, 0, -2.5]
},
"ear_ruff_shock_right2": {
"rotation": [0, 0, 12.5]
}
}
},
"animation.braixen.shock": {
"loop": true,
"bones": {
"jaw": {
"rotation": [47.5, 0, 0]
},
"pupil_left": {
"position": [-0.1, 0, 0],
"scale": [0.6, 0.6, 1]
},
"pupil_right": {
"position": [0.1, 0, 0],
"scale": [0.6, 0.6, 1]
}
}
},
"animation.braixen.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.braixen.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0.1, 0, -0.1]
},
"eye_sad_right": {
"position": [-0.1, 0, -0.1]
},
"pupil_left": {
"position": [0.09, 0, 0]
},
"pupil_right": {
"position": [-0.09, 0, 0]
}
}
},
"animation.braixen.happy": {
"loop": true,
"bones": {
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
},
"jaw": {
"rotation": [47.5, 0, 0]
}
}
},
"animation.braixen.blush": {
"loop": true,
"bones": {
"blush_left": {
"position": [0.1, 0, 0]
},
"blush_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.braixen.hurt": {
"loop": true,
"bones": {
"eyelid_recoil_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_recoil_right": {
"position": [-0.1, 0, -0.1]
}
}
}
}
}
@@ -3,295 +3,443 @@
"animations": {
"animation.delphox.ground_idle": {
"loop": true,
"animation_length": 8,
"bones": {
"head": {
"rotation": ["10+math.sin(q.anim_time*90*1-15)*2", 0, 0]
},
"ear_ruff_top_right": {
"rotation": [0, 7.5, -10],
"position": [-0.3, 0, 0.5]
},
"ear_ruff_top_right2": {
"rotation": [0, 15, "-math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_top_right3": {
"rotation": [0, 7.5, "10-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_middle_right": {
"rotation": [0, -2.5, -12.5]
},
"ear_ruff_middle_right2": {
"rotation": [0, 20, "5-math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_middle_right3": {
"rotation": [0, 15, "7.5-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_bottom_right": {
"rotation": [0, 10, -17.5],
"position": [-0.1, 0, 0.25]
},
"ear_ruff_bottom_right2": {
"rotation": [0, 10, "12.5-math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_bottom_right3": {
"rotation": [0, 17.5, "12.5-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_top_left": {
"rotation": [0, -7.5, 10],
"position": [0.3, 0, 0.5]
},
"ear_ruff_top_left2": {
"rotation": [0, -15, "math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_top_left3": {
"rotation": [0, -7.5, "-10+math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_middle_left": {
"rotation": [0, 2.5, 12.5]
},
"ear_ruff_middle_left2": {
"rotation": [0, -20, "-5+math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_middle_left3": {
"rotation": [0, -15, "-7.5+math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_bottom_left": {
"rotation": [0, -10, 17.5],
"position": [0.1, 0, 0.25]
},
"ear_ruff_bottom_left2": {
"rotation": [0, -10, "-12.5+math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_bottom_left3": {
"rotation": [0, -17.5, "-12.5+math.sin(q.anim_time*90*1-215)*3"]
},
"arm_right": {
"rotation": [0, "-12.5+math.sin(q.anim_time*90*1+30)*2", -52.5]
},
"arm_right2": {
"rotation": [3.31914, "-14.6364+math.sin(q.anim_time*90*1+90)*2", -12.92638]
},
"hand_right": {
"rotation": [0, 0, -12.5]
},
"finger_index_right": {
"rotation": [0, 0, -50]
},
"finger_middle_right": {
"rotation": [0, 0, -52.5]
},
"finger_ring_right": {
"rotation": [0, 0, -60]
},
"arm_left": {
"rotation": [1.36797, "-32.4703+math.sin(q.anim_time*90*1-15)*2", "57.0477+math.sin(q.anim_time*90*1-60)*3"]
"rotation": [0, -5, 60]
},
"arm_left2": {
"rotation": [-0.82097, "60.3299+math.sin(q.anim_time*90*1-95)*4", "3.238+math.sin(q.anim_time*90*1-180)*4"]
"rotation": [0, 12.5, 0]
},
"hand_left": {
"rotation": [0, 0, 20]
},
"finger_index_left": {
"rotation": [0, 0, 15]
},
"finger_middle_left": {
"rotation": [0, 0, 10]
},
"finger_ring_left": {
"rotation": [0, 0, 5]
},
"tail": {
"rotation": ["-12.5+math.sin(q.anim_time*90*2)*4", "math.sin(q.anim_time*90*1-90)*8", "math.sin(q.anim_time*90*1-90)*2"]
},
"tail2": {
"rotation": [-15, "math.sin(q.anim_time*90*1-90-45)*8", 0]
},
"tail3": {
"rotation": [-12.5, "math.sin(q.anim_time*90*1-90-90)*8", 0]
},
"tail4": {
"rotation": [15, "math.sin(q.anim_time*90*1-90-135)*8", 0]
},
"tail5": {
"rotation": [12.5, "math.sin(q.anim_time*90*1-90-180)*8", 0]
},
"leg_right": {
"rotation": [0, 15, 0]
},
"leg_left": {
"rotation": [0, -17.5, 0]
},
"body": {
"rotation": [0, -12.5, 0]
},
"torso": {
"rotation": ["math.sin(q.anim_time*90*1-135)*1", 3.5, 0],
"position": [0, 0, 0]
},
"chest": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-90)*2", 8, 0]
},
"neck": {
"rotation": [0, 0, 0],
"position": [0, 0, -0.25]
},
"head_ruff_right": {
"rotation": [0, "7.5+math.sin(q.anim_time*90*1-90)*2", 0]
},
"head_ruff_left": {
"rotation": [0, "-7.5-math.sin(q.anim_time*90*1-90)*2", 0]
},
"ear_right_main": {
"rotation": ["-10+math.sin(q.anim_time*90*1-150)*3", 0, 0]
},
"ear_right": {
"rotation": [0, 0, "2.55+math.sin(q.anim_time*90*1-150)*1"]
},
"ear_right_ruff_main": {
"rotation": [0, "2.5+math.sin(q.anim_time*90*1-45)*3", "4-math.sin(q.anim_time*90*1-135)*1.5"],
"position": [-0.2, 0, 0]
},
"ear_left_main": {
"rotation": ["-10+math.sin(q.anim_time*90*1-150)*3", 0, 0]
},
"ear_left": {
"rotation": [0, 0, "-2.55-math.sin(q.anim_time*90*1-150)*1"]
},
"ear_left_ruff_main": {
"rotation": [0, "-2.5-math.sin(q.anim_time*90*1-45)*3", "-4+math.sin(q.anim_time*90*1-135)*1.5"],
"position": [0.2, 0, 0]
},
"hand_stick": {
"position": [4.9, -1, 0]
},
"finger_index_right2": {
"rotation": [0, 0, -60]
},
"finger_middle_right2": {
"rotation": [0, 0, -57.5]
},
"finger_ring_right2": {
"rotation": [0, 0, -42.5]
},
"arm_left_ruff": {
"rotation": ["-15+math.sin(q.anim_time*90*1+45)*10", 0, 0]
},
"chest_ruff_top_right": {
"rotation": [0, 0, -40]
},
"chest_ruff_top_left": {
"rotation": [0, 0, 40]
},
"chest_ruff_right_top": {
"rotation": [0, 0, "7.5+math.sin(q.anim_time*90*1)*2"]
},
"chest_ruff_right_bottom": {
"rotation": [0, 0, "-2.5+math.sin(q.anim_time*90*1-45)*2"]
},
"chest_ruff_right_bottom2": {
"rotation": [0, 0, "-20+math.sin(q.anim_time*90*1-90)*2"]
},
"chest_ruff_left_top": {
"rotation": [0, 0, "-12.5-math.sin(q.anim_time*90*1)*2"]
},
"chest_ruff_left_bottom": {
"rotation": [0, 0, "5-math.sin(q.anim_time*90*1-45)*2"]
},
"chest_ruff_left_bottom2": {
"rotation": [0, 0, "15-math.sin(q.anim_time*90*1-90)*2"]
},
"leg_right_outer2": {
"rotation": [0, 0, "-0.35+math.sin(q.anim_time*90*1-45)*0.5"]
},
"leg_right_outer4": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-90)*2"]
},
"leg_right_outer5": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-135)*2"]
},
"leg_right_outer6": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-180)*2"]
},
"leg_right_outer7": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-215)*2"]
},
"leg_left_outer": {
"rotation": [0, 0, 0]
},
"leg_left_outer2": {
"rotation": [0, 0, "0.35-math.sin(q.anim_time*90*1-45)*0.5"]
},
"leg_left_outer4": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-90)*2"]
},
"leg_left_outer5": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-135)*2"]
},
"leg_left_outer6": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-180)*2"]
},
"leg_left_outer7": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-215)*2"]
},
"flame": {
"rotation": [
"-40+3*(math.sin(q.anim_time*90*3*2-90)*1-1)+6*(math.sin(q.anim_time*90*3/2-90)*1-1)",
"-35+5*(math.sin(q.anim_time*90*3-150)*1-1)+6*(math.sin(q.anim_time*90*3/2-90)*1-1)",
35
]
},
"torso_cloak": {
"rotation": [-5, 0, 0]
},
"shoulder_left_ruff": {
"rotation": [-12.5, 0, 0]
},
"arm_left_ruff2": {
"rotation": [-10, 0, 0]
},
"finger_front_left": {
"rotation": [0, 0, 17.5]
},
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"finger_back_left": {
"rotation": [0, 0, 35]
"rotation": [0, 0, 30]
},
"arm_right_ruff": {
"rotation": [-5, 0, 0]
"arm_right": {
"rotation": [0, 5, -60]
},
"arm_right_ruff2": {
"rotation": [-10, 0, 0]
},
"finger_front_right": {
"rotation": [0, 0, -40]
},
"finger_back_right": {
"rotation": [0, 0, -60]
},
"stick_hand": {
"scale": 0
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_top_left4": {
"arm_right2": {
"rotation": [0, -12.5, 0]
},
"ear_ruff_middle_left4": {
"rotation": [0, -10, 0]
"hand_right": {
"rotation": [0, 0, -15]
},
"ear_ruff_shock_right": {
"finger_front_right": {
"rotation": [0, 0, -17.5]
},
"finger_back_right": {
"rotation": [0, 0, -30]
},
"head": {
"rotation": ["5+math.sin(q.anim_time*90*1)*-1", 0, 0]
},
"ear_left_ruff_main": {
"rotation": [0.18349, -15.01207, 0.11941]
},
"ear_ruff_top_left": {
"rotation": [0, -5, 0]
},
"ear_ruff_middle_left": {
"rotation": [-5, 10, 0]
},
"ear_right_ruff_main": {
"rotation": [0.18349, 15.01207, -0.11941]
},
"ear_ruff_top_right": {
"rotation": [0, 5, 0]
},
"ear_ruff_middle_right": {
"rotation": [-5, -10, 0]
},
"leg_left": {
"rotation": [-10.50431, -1.61684, -2.5578],
"position": [0, 0, -0.5]
},
"leg_left3": {
"rotation": [1.5, 0, 0]
},
"foot_left": {
"rotation": [4.48529, -0.57217, 2.94498]
},
"leg_right": {
"rotation": [1.10693, 12.45167, 5.12076]
},
"leg_right3": {
"rotation": [0, 0, -2.5]
},
"foot_right": {
"rotation": [0, 0, -3]
},
"torso": {
"rotation": ["2.5+math.sin(q.anim_time*90*1)*1", 0, 0],
"position": [0, "math.cos(q.anim_time*90*1)*0.2", 0]
},
"waist": {
"rotation": ["-1+math.sin(q.anim_time*90*1-30)*1", 0, 0]
},
"tail": {
"rotation": [-23, 0, 0]
},
"robe_left": {
"rotation": [0, 2.5, 0]
},
"robe_left_outer2": {
"rotation": [0, -2.5, 0]
},
"tail2": {
"rotation": [-12.5, 0, 0]
},
"tail3": {
"rotation": [-20, 0, 0]
},
"tail4": {
"rotation": [5, 0, 0]
},
"tail5": {
"rotation": [25, 0, 0]
},
"tail6": {
"rotation": [17.5, 0, 0]
},
"tail7": {
"rotation": [-7.5, 0, 0]
},
"ear_ruff_shock_left": {
"rotation": [0, -5, 0],
"scale": 0
},
"ear_ruff_top_right4": {
"rotation": [0, 12.5, 0]
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"ear_ruff_middle_right4": {
"rotation": [0, 10, 0]
"body": {
"position": [0, -0.2, 0]
},
"torso_cloak": {
"rotation": [-1, 0, 0]
},
"finger_middle_right": {
"rotation": [0, 0, -12.5]
},
"neck": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-30)*-2", 0, 0]
},
"ear_ruff_bottom_left": {
"rotation": [0, -2.5, 15]
},
"ear_ruff_bottom_right": {
"rotation": [0, 2.5, -15]
},
"leg_left2": {
"rotation": [5, 0, 0]
},
"leg_right2": {
"rotation": [2.5, 0, 0]
},
"robe_left_outer": {
"rotation": [0, 2.5, 0]
},
"robe_left_outer3": {
"rotation": [0, -2.5, 0]
},
"chest": {
"rotation": ["math.sin(q.anim_time*90*1)*-1", 0, 0]
},
"ear_right": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1-60)*2"]
},
"ear_right_main": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1-30)*1"]
},
"robe_right": {
"rotation": [0, 2.5, 0]
},
"robe_right_outer": {
"rotation": [0, 2.5, 0]
},
"robe_right_outer2": {
"rotation": [0, -2.5, 0]
},
"robe_right_outer3": {
"rotation": [0, -2.5, 0]
},
"wand": {
"scale": 0
}
}
},
"animation.delphox.battle_idle": {
"loop": true,
"animation_length": 8,
"bones": {
"body": {
"rotation": [0, -10, 0],
"position": [0, -3, 0]
},
"torso": {
"rotation": ["30+math.sin(q.anim_time*90*1.5)*1", -17.5, -2.5],
"position": [0.25, "0.25+math.cos(q.anim_time*90*1.5)*-0.2", -0.5]
},
"waist": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-30)*1", -2.5, 5]
},
"chest": {
"rotation": ["-7.5+math.sin(q.anim_time*90*1.5-75)*1", -5, -2.5]
},
"arm_left": {
"rotation": [-10, -27.5, 25],
"position": [1, -0.35, 1]
},
"arm_left2": {
"rotation": [-7.5, 75, -7.5]
},
"finger_front_left": {
"rotation": [0, 0, 47.5]
},
"finger_middle_left": {
"rotation": [0, 0, 62.5]
},
"finger_back_left": {
"rotation": [0, 0, 75]
},
"arm_right": {
"rotation": [-57.5, -30, -25],
"position": [-1, -0.75, 0.25]
},
"arm_right2": {
"rotation": [7.5, -55, -17.5]
},
"arm_right_ruff": {
"rotation": [-15, 15, -7.5]
},
"hand_right": {
"rotation": [0, 22.5, 0],
"position": [-0.25, 0, 0]
},
"finger_front_right": {
"rotation": [0, 0, -50]
},
"finger_middle_right": {
"rotation": [0, 0, -55]
},
"finger_back_right": {
"rotation": [0, 0, -65]
},
"ear_left_ruff_main": {
"rotation": [0.18349, -15.01207, 0.11941]
},
"ear_ruff_top_left": {
"rotation": [0, -5, 0]
},
"ear_ruff_middle_left": {
"rotation": [-5, 10, 0]
},
"ear_ruff_bottom_left": {
"rotation": [0, -2.5, 15]
},
"ear_right_ruff_main": {
"rotation": [0.18349, 15.01207, -0.11941]
},
"ear_ruff_top_right": {
"rotation": [0, 5, 0]
},
"ear_ruff_middle_right": {
"rotation": [-5, -10, 0]
},
"ear_ruff_bottom_right": {
"rotation": [0, 2.5, -15]
},
"leg_left": {
"rotation": [7.5, -10, -15],
"position": [0.25, -0.25, 1]
},
"leg_left2": {
"rotation": [22.5, 0, -7.5]
},
"leg_left3": {
"rotation": [-2.5, 0, 0]
},
"foot_left": {
"rotation": [-21.5, 0, 20],
"position": [-0.5, -1.5, -0.75]
},
"leg_right": {
"rotation": [-27.5, 0, 7.5],
"position": [0, 0, -1]
},
"leg_right2": {
"rotation": [17.5, 0, 0]
},
"leg_right3": {
"rotation": [-7.5, 7.5, 10]
},
"foot_right": {
"rotation": [17.5, 17.5, -12.5],
"position": [0.25, -0.25, 0]
},
"wand": {
"rotation": [0, 0, 77.5],
"position": [1, 0, 0]
},
"ear_ruff_shock_left": {
"rotation": [0, -5, 0],
"scale": 0
},
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"body_wand": {
"rotation": [0, -10, 0],
"position": [0, -3, 0]
},
"torso_wand": {
"rotation": ["30+math.sin(q.anim_time*90*1.5)*1", -17.5, -2.5],
"position": [0.25, "0.25+math.cos(q.anim_time*90*1.5)*-0.2", -0.5]
},
"waist_wand": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-30)*1", -2.5, 5]
},
"chest_wand": {
"rotation": ["-7.5+math.sin(q.anim_time*90*1.5-75)*1", -5, -2.5]
},
"arm_wand": {
"rotation": [-57.5, -30, -25],
"position": [-1, -0.75, 0.25]
},
"arm2_wand": {
"rotation": [7.5, -55, -17.5]
},
"hand_wand": {
"rotation": [0, 22.5, 0],
"position": [-0.25, 0, 0]
},
"hand_left": {
"rotation": [-12.5, 32.5, -15]
},
"shoulder_right_ruff": {
"rotation": [0, 10, 0]
},
"torso_cloak": {
"rotation": [-27.5, 0, 0]
},
"shoulder_left_ruff": {
"rotation": [-12.5, 0, 0]
},
"arm_left_ruff": {
"rotation": [-35, 0, 0]
},
"arm_left_ruff2": {
"rotation": [-15, 0, 0]
},
"neck": {
"rotation": ["17.5+math.sin(q.anim_time*90*1.5-110)*-2", 20, 5],
"position": [0, -1, 0]
},
"head": {
"rotation": ["-20+math.sin(q.anim_time*90*1.5-90)*3", "15+math.sin(q.anim_time*90*1.5-90)*-2", -15]
},
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
},
"head_ruff_right": {
"rotation": [-1.64071, -0.82614, -1.75664]
},
"shoulder_fur_left": {
"rotation": [0, 0, -35]
},
"shoulder_fur_right": {
"rotation": [0, 0, 35]
},
"tail": {
"rotation": ["-8+math.sin(q.anim_time*90*1.5-90)*10", "math.sin(q.anim_time*90*1-90)*20", 0],
"position": [0, 1, 0]
},
"tail2": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-120)*12", "math.sin(q.anim_time*90*1-120)*25", 0]
},
"tail3": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-170)*13", "math.sin(q.anim_time*90*1-170)*30", 0]
},
"tail4": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-210)*18", "math.sin(q.anim_time*90*1-200)*35", 0]
},
"tail5": {
"rotation": ["10+math.sin(q.anim_time*90*1.5-260)*22", "math.sin(q.anim_time*90*1-250)*35", 0]
},
"tail6": {
"rotation": ["5+math.sin(q.anim_time*90*1.5-260)*25", "math.sin(q.anim_time*90*1-290)*40", 0]
},
"tail7": {
"rotation": ["math.sin(q.anim_time*90*1.5-290)*50", "math.sin(q.anim_time*90*1-310)*45", 0]
},
"robe_left": {
"rotation": [20, -15, -15],
"position": [0, 0, 1]
},
"robe_left2_rotation": {
"rotation": [-5, 0, 2.5]
},
"robe_left3_rotation": {
"rotation": [-2.5, 0, 0]
},
"robe_left_outer": {
"rotation": [0, -2.5, 0]
},
"robe_left_outer2": {
"rotation": [0, -5, 0]
},
"robe_right": {
"rotation": [-15, -2.5, 15],
"position": [0, -0.75, -1]
},
"robe_right2_rotation": {
"rotation": [5, 0, 2.5]
},
"robe_right3_rotation": {
"rotation": [5, 0, -2.5]
},
"robe_right_outer": {
"rotation": [0, 2.5, 0]
},
"robe_right_outer2": {
"rotation": [2.5, 5, 0]
},
"robe_right_outer3": {
"rotation": [0, 5, 0]
},
"robe_front_middle": {
"rotation": [-7.5, -20, -5],
"position": [1.5, 0, -1.65]
},
"robe_front_middle2_rotation": {
"rotation": [-2.5, -7.5, -0.5],
"position": [-1, -1, 0]
},
"robe_front_middle3_rotation": {
"rotation": [5, 7.5, -5],
"position": [-1.86367, 0.85692, -0.23757]
},
"robe_middle_front_fur": {
"rotation": [-10, 0, 0]
},
"robe_front_middle3": {
"rotation": [0, -10, 7.5]
}
}
},
"animation.delphox.battle_idle2_wip": {
"loop": true,
"bones": {
"robe_left": {
@@ -481,20 +629,6 @@
"foot_right2": {
"rotation": [0, 0, 0]
},
"robe_right": {
"rotation": [-34.35188, 12.84924, 4.16618],
"position": [0, 0, -1]
},
"robe_right2": {
"rotation": [32.62765, -10.18372, 3.05577],
"position": [0, -1, 0]
},
"robe_right2_rotation": {
"rotation": [2.41492, 0.64686, -14.98637]
},
"robe_right3_rotation": {
"rotation": [0, 0, 5]
},
"tail2": {
"rotation": [-17.56274, -4.76804, 1.50701]
},
@@ -513,7 +647,7 @@
"tail7": {
"rotation": [-27.5, 0, 0]
},
"stick_hand": {
"wand": {
"rotation": [115.18907, -6.79382, 69.31542],
"position": [7.5, -2, -2]
},
@@ -530,6 +664,34 @@
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"robe_right": {
"rotation": [28.44706, -2.60661, -11.92606],
"position": [1, 0, 0]
},
"robe_right2_rotation": {
"rotation": [-17.10967, 3.73172, 11.93845],
"position": [0, -1, 0]
},
"robe_right3_rotation": {
"rotation": [-7.5, 0, 0]
}
}
},
"animation.delphox.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.1667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.1667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
}
}
},
@@ -817,7 +979,7 @@
"finger_back_right": {
"rotation": [0, 0, -45]
},
"stick_hand": {
"wand": {
"scale": 0
},
"ear_ruff_shock_left": {
@@ -866,25 +1028,6 @@
}
}
},
"animation.delphox.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": [0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.125": [-0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.delphox.cry": {
"animation_length": 1.75,
"bones": {
@@ -952,170 +1095,6 @@
"effect": "pokemon.delphox.cry"
}
}
},
"animation.delphox.surprise_hair": {
"animation_length": 0.0417,
"bones": {
"ear_ruff_top_left": {
"rotation": [0.86996, -0.48705, -9.93723]
},
"ear_ruff_top_left2": {
"rotation": [0, 0, 0]
},
"ear_ruff_top_left3": {
"rotation": [0, 0, -10]
},
"ear_ruff_top_left4": {
"rotation": [0, 0, -25]
},
"ear_ruff_middle_left": {
"rotation": [0, 0, 7.5]
},
"ear_ruff_middle_left2": {
"rotation": [0, 0, -12.5]
},
"ear_ruff_middle_left3": {
"rotation": [-1.63786, -2.36303, 19.89762]
},
"ear_ruff_middle_left4": {
"rotation": [0, 0, -25]
},
"ear_ruff_bottom_left": {
"rotation": {
"0.0": [0.1467, 0.51916, 9.98614],
"0.0417": [0.23463, 0.48579, 19.98647]
}
},
"ear_ruff_bottom_left2": {
"rotation": [-0.08929, 0.02949, 17.49954]
},
"ear_ruff_bottom_left3": {
"rotation": [0, 0, 2.5]
},
"ear_ruff_top_right": {
"rotation": [0.86996, 0.48705, 9.93723]
},
"ear_ruff_top_right2": {
"rotation": [0, 0, 0]
},
"ear_ruff_top_right3": {
"rotation": [0, 0, 10]
},
"ear_ruff_top_right4": {
"rotation": [0, 0, 25]
},
"ear_ruff_middle_right2": {
"rotation": [0, 0, 12.5]
},
"ear_ruff_middle_right3": {
"rotation": [-1.63786, 2.36303, -19.89762]
},
"ear_ruff_middle_right4": {
"rotation": [0, 0, 25]
},
"ear_ruff_middle_right": {
"rotation": [0, 0, -7.5]
},
"ear_ruff_bottom_right": {
"rotation": [0.1467, -0.51916, -9.98614]
},
"ear_ruff_bottom_right2": {
"rotation": [-0.08929, -0.02949, -17.49954]
},
"ear_ruff_bottom_right3": {
"rotation": [0, 0, -2.5]
},
"ear_ruff_shock_left_top": {
"rotation": [0, 0, -22.5]
},
"ear_ruff_shock_left_middle": {
"rotation": [0, 0, 7.5]
},
"ear_ruff_shock_left_bottom": {
"rotation": [0, 0, 25]
},
"ear_ruff_shock_right_top": {
"rotation": [0, 0, 22.5]
},
"ear_ruff_shock_right_middle": {
"rotation": [0, 0, -7.5]
},
"ear_ruff_shock_right_bottom": {
"rotation": [0, 0, -25]
}
}
},
"animation.delphox.shock": {
"loop": true,
"bones": {
"jaw": {
"rotation": [62.5, 0, 0]
},
"pupil_left": {
"scale": [0.6, 0.6, 1]
},
"pupil_right": {
"scale": [0.6, 0.6, 1]
}
}
},
"animation.delphox.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.delphox.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0.1, 0, -0.1]
},
"eye_sad_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.delphox.happy": {
"loop": true,
"bones": {
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
},
"jaw": {
"rotation": [62.5, 0, 0]
}
}
},
"animation.delphox.blush": {
"loop": true,
"bones": {
"blush_left": {
"position": [0.1, 0, 0]
},
"blush_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.delphox.hurt": {
"loop": true,
"bones": {
"eyelid_recoil_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_recoil_right": {
"position": [-0.1, 0, -0.1]
}
}
}
}
}
@@ -280,6 +280,14 @@
"rotation": [-5, 10, -7.5]
}
}
},
"animation.sylveon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.sylveon.cry"
}
}
}
}
}
@@ -155,6 +155,9 @@
"back_neck_braid_right4": {
"rotation": [2.5, 0, -10],
"position": [-0.5, 0, 0]
},
"body": {
"rotation": ["q.riding.velocity_y(0)*-90", 0, 0]
}
}
},
@@ -650,7 +653,7 @@
}
},
"neck2": {
"rotation": ["5+math.sin(q.anim_time*90*4-60)*2", 0, 0]
"rotation": ["5+math.sin(q.anim_time*90*4-60)*2 - math.pow(q.riding.yaw_change(0),2)*20", "q.riding.yaw_change(0)*-10", "q.riding.yaw_change(0)*10"]
},
"tail5": {
"rotation": ["-7.5+math.sin(q.anim_time*90*4-90)*2", "math.sin(q.anim_time*90*2)*1", "math.sin(q.anim_time*90*2)*4"]
@@ -677,7 +680,7 @@
}
},
"neck": {
"rotation": ["3+math.sin(q.anim_time*90*4-30)*1", 0, "math.sin(q.anim_time*90*2-30)*2"]
"rotation": ["3+math.sin(q.anim_time*90*4-30)*1", "q.riding.yaw_change(0)*-10", "math.sin(q.anim_time*90*2-30)*2 + q.riding.yaw_change(0)*10"]
},
"front_neck_braid_left": {
"rotation": ["5+math.sin(q.anim_time*90*4-60)*1", 0.5, 5]
@@ -844,6 +847,7 @@
"position": [-0.5, 0, 0]
},
"body": {
"rotation": ["q.riding.velocity_y(0)*-90", 0, 0],
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.25, 0],
@@ -1257,7 +1261,7 @@
}
},
"neck2": {
"rotation": ["math.sin(q.anim_time*90*4-60)*4", 0, 0]
"rotation": ["math.sin(q.anim_time*90*4-60)*4 - math.pow(q.riding.yaw_delta(0),2)*20", "q.riding.yaw_delta(0)*-10", "q.riding.yaw_delta(0)*10"]
},
"tail5": {
"rotation": ["-10+math.sin(q.anim_time*90*4-100)*6", "math.sin(q.anim_time*90*4-40)*2", "math.sin(q.anim_time*90*4-20)*1"]
@@ -1279,7 +1283,7 @@
}
},
"neck": {
"rotation": ["13+math.sin(q.anim_time*90*4-30)*7", 0, 0],
"rotation": ["13+math.sin(q.anim_time*90*4-30)*7", "q.riding.yaw_delta(0)*-10", "q.riding.yaw_delta(0)*10"],
"position": [0, 0, "-0.5+math.sin(q.anim_time*90*4-30)*0.2"]
},
"front_neck_braid_left": {
@@ -5,20 +5,20 @@
"loop": true,
"bones": {
"body": {
"position": [0, -0.7, 0]
},
"waist": {
"rotation": [0, 0, 9],
"position": [0, -0.2, 0]
"position": [0, -0.6, 0]
},
"torso": {
"rotation": [0, 0, -9]
"rotation": [-3, 5, 1.5],
"position": [0, -0.2, 0]
},
"torso2": {
"rotation": [4, 0, -1.5]
},
"head": {
"rotation": [0, 0, 0]
"rotation": [0, -5, 0]
},
"feather": {
"rotation": [-47.5, 22.5, 0]
"rotation": [-47.5, 28, 0]
},
"feather2": {
"rotation": [-35, 0, 0]
@@ -30,13 +30,13 @@
"rotation": [-32.5, 0, 0]
},
"arm_right": {
"rotation": [30, 22.5, -46.5]
"rotation": [30, 22.5, -52]
},
"arm_right2": {
"rotation": [45, -90, 0]
},
"hand_right": {
"rotation": [10, 5, -15]
"rotation": [20, 10, -15]
},
"arm_claw_back_right": {
"rotation": [0, 0, -30]
@@ -63,14 +63,14 @@
"rotation": [-20, 0, 0]
},
"leg_right": {
"rotation": [1.5, 5, 8],
"rotation": [5, 15, 8],
"position": [0, 0.4, 0]
},
"leg_right2": {
"rotation": [3, 0, 0]
"rotation": [0, 0, 0]
},
"foot_right": {
"rotation": [-3.5, 0, 0]
"rotation": [0, 0, 0]
},
"feather5": {
"rotation": [-27.5, 0, 0]
@@ -85,14 +85,14 @@
"rotation": [25, 0, 0]
},
"leg_left": {
"rotation": [-15, -15, -8],
"rotation": [-12.5, -15, -8],
"position": [0, -0.8, 0]
},
"leg_right3": {
"rotation": [0, 0, -8]
"rotation": [-2.5, 0, -7]
},
"leg_left2": {
"rotation": [25, 0, 0]
"rotation": [22.5, 0, 0]
},
"leg_left3": {
"rotation": [0, 0, 8]
@@ -102,62 +102,317 @@
}
}
},
"animation.sneasler.mouth_test": {
"animation_length": 2,
"animation.sneasler.battle_idle": {
"loop": true,
"bones": {
"fang": {
"rotation": {
"0.0": [0, 0, 0],
"0.6667": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.7083": {"pre": [0, 0, 0], "post": [0, 0, 11.5]},
"1.5": {"pre": [0, 0, 11.5], "post": [0, 0, 11.5]},
"1.5417": {"pre": [0, 0, 11.5], "post": [0, 0, 0]}
},
"position": {
"0.0": [0, 0, 0],
"0.6667": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.7083": {"pre": [0, 0, 0], "post": [0, 0.7, 0.4]},
"1.5": {"pre": [0, 0.7, 0.4], "post": [0, 0.7, 0.4]},
"1.5417": {"pre": [0, 0.7, 0.4], "post": [0, 0, 0]}
}
"locator_top": {
"position": [0, -4, 0]
},
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.6667": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.7083": {"pre": [0, 0, 0], "post": [0, 0, 0.61]},
"1.5": {"pre": [0, 0, 0.61], "post": [0, 0, 0.61]},
"1.5417": {"pre": [0, 0, 0.61], "post": [0, 0, 0]}
}
"body": {
"rotation": [0, 20, 0],
"position": [0, -4.6, 0]
},
"torso": {
"rotation": [-5, 15, 0]
},
"torso2": {
"rotation": [12, 0, 0]
},
"neck": {
"rotation": [20, 0, 0]
},
"head": {
"rotation": [-26, -31, 18],
"position": [0, 0, -0.2]
},
"feather": {
"rotation": [-47.5, 28, 0]
},
"feather2": {
"rotation": [-35, 0, 0]
},
"feather3": {
"rotation": [-50, 0, 0]
},
"feather4": {
"rotation": [-32.5, 0, 0]
},
"feather5": {
"rotation": [-27.5, 0, 0]
},
"feather6": {
"rotation": [15, 0, 0]
},
"feather7": {
"rotation": [22.5, 0, 0]
},
"feather8": {
"rotation": [25, 0, 0]
},
"arm_right": {
"rotation": [-32.5, 50, -65]
},
"arm_right2": {
"rotation": [0, -70, 0]
},
"hand_right": {
"rotation": [5, -5, -5]
},
"arm_claw_back_right": {
"rotation": [0, 5, -10]
},
"arm_claw_middle_right": {
"rotation": [0, 0, -2]
},
"arm_claw_front_right": {
"rotation": [0, -5, 5]
},
"arm_left": {
"rotation": [-5, 0, 0]
},
"arm_left2": {
"rotation": [-5, 85, 0]
},
"hand_left": {
"rotation": [-5, 10, 0]
},
"arm_claw_back_left": {
"rotation": [0, -10, 15]
},
"arm_claw_middle_left": {
"rotation": [0, 0, 5]
},
"arm_claw_front_left": {
"rotation": [0, 10, -5]
},
"leg_right": {
"rotation": [-14.5, 40, 45],
"position": [-0.5, 0, 1]
},
"leg_right2": {
"rotation": [64, 0, 0],
"position": [0, 0, 1]
},
"leg_right3": {
"rotation": [-9.5, -2.5, -33.5],
"position": [0, -0.4, 0]
},
"foot_right": {
"rotation": [-4.5, 0, 0]
},
"leg_left": {
"rotation": [-30, -35, -32],
"position": [0, 0, -1]
},
"leg_left2": {
"rotation": [25, 0, 5]
},
"leg_left3": {
"rotation": [15.5, 0, 24.5]
},
"foot_left": {
"rotation": [5.5, 0, 0],
"position": [0, 0.6, 0]
}
}
},
"animation.sneasler.ground_idle_basket": {
"loop": true,
"bones": {
"body": {
"position": [0, -0.2, 0]
},
"torso": {
"rotation": [-2.5, 0, 0]
},
"torso2": {
"rotation": [3, 0, 0]
},
"basketstrap_right": {
"rotation": [-17.5, 10, 5]
},
"basketstrap_right3": {
"rotation": [-22, 0, 0]
},
"shoulder_fluff_right": {
"rotation": [0, 0, -15],
"position": [-0.5, 0, 0]
},
"shoulder_fluff_left": {
"rotation": [0, 0, 15],
"position": [0.5, 0, 0]
},
"neck": {
"rotation": [2, 0, 0]
},
"head": {
"rotation": [-1, 0, 0]
},
"feather": {
"rotation": [-47.5, 33, 0]
},
"feather2": {
"rotation": [-35, 0, 0]
},
"feather3": {
"rotation": [-50, 0, 0]
},
"feather4": {
"rotation": [-32.5, 0, 0]
},
"feather5": {
"rotation": [-27.5, 0, 0]
},
"feather6": {
"rotation": [15, 0, 0]
},
"feather7": {
"rotation": [22.5, 0, 0]
},
"feather8": {
"rotation": [25, 0, 0]
},
"arm_right": {
"rotation": [-12, 7.5, -62]
},
"arm_right2": {
"rotation": [0, -15, -2.5]
},
"hand_right": {
"rotation": [0, 0, -2.5]
},
"arm_claw_middle_right": {
"rotation": [0, 0, -5]
},
"arm_claw_front_right": {
"rotation": [0, 0, -10]
},
"arm_left": {
"rotation": [-12, -7.5, 62]
},
"arm_left2": {
"rotation": [0, 15, 2.5]
},
"hand_left": {
"rotation": [0, 0, 2.5]
},
"arm_claw_middle_left": {
"rotation": [0, 0, 5]
},
"arm_claw_front_left": {
"rotation": [0, 0, 10]
},
"leg_right": {
"rotation": [-2.5, 12, 5.5],
"position": [-0.3, 0, 0]
},
"leg_right2": {
"rotation": [5, 0, 0]
},
"leg_right3": {
"rotation": [-1, 0, -5]
},
"leg_left": {
"rotation": [-2.5, -12, -5.5],
"position": [0.3, 0, 0]
},
"leg_left2": {
"rotation": [5, 0, 0]
},
"leg_left3": {
"rotation": [-1, 0, 5]
},
"basketstrap_right4": {
"rotation": [35, 0, 0]
},
"shoulder_fluff_back_right": {
"rotation": [0, 0, 0]
},
"shoulder_fluff_front_right": {
"rotation": [15, 0, 0]
},
"shoulder_fluff_back_left": {
"rotation": [0, 0, 0]
},
"shoulder_fluff_front_left": {
"rotation": [15, 0, 0]
},
"basketstrap_right2": {
"rotation": [52, 0, 0]
},
"basketstrap_left": {
"rotation": [-17.5, -10, -5]
},
"basketstrap_left2": {
"rotation": [52, 0, 0]
},
"basketstrap_left3": {
"rotation": [-22, 0, 0]
},
"basketstrap_left4": {
"rotation": [35, 0, 0]
}
}
},
"animation.sneasler.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"0.0": [-0.1, 0, -0.1],
"0.125": {
"pre": [-0.1, 0, -0.1],
"post": [-0.1, 0, -0.1]
},
"0.1667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"0.0": [0.1, 0, -0.1],
"0.125": {
"pre": [0.1, 0, -0.1],
"post": [0.1, 0, -0.1]
},
"0.1667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelashes_right": {
"position": {
"0.0": [0.1, 0, 0.1],
"0.125": {
"pre": [0.1, 0, 0.1],
"post": [0.1, 0, 0.1]
},
"0.1667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"eyelashes_left": {
"position": {
"0.0": [-0.1, 0, 0.1],
"0.125": {
"pre": [-0.1, 0, 0.1],
"post": [-0.1, 0, 0.1]
},
"0.1667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
}
}
}
}
},
"animation.sneasler.cry": {
"animation_length": 1,
"sound_effects": {
"0.04": {
"effect": "pokemon.sneasler.cry"
}
},
"bones": {
"head": {
"rotation": {
@@ -171,24 +426,25 @@
"0.5": [0, 0, 0]
}
},
"fang": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0, 0, 11.5]},
"0.1667": {"pre": [0, 0, 11.5], "post": [0, 0, 11.5]},
"0.2083": {"pre": [0, 0, 11.5], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 11.5]},
"0.4583": {"pre": [0, 0, 11.5], "post": [0, 0, 11.5]},
"0.5": {"pre": [0, 0, 11.5], "post": [0, 0, 0]}
},
"fang_closed": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0, 0.7, 0.4]},
"0.1667": {"pre": [0, 0.7, 0.4], "post": [0, 0.7, 0.4]},
"0.2083": {"pre": [0, 0.7, 0.4], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0.7, 0.4]},
"0.4583": {"pre": [0, 0.7, 0.4], "post": [0, 0.7, 0.4]},
"0.5": {"pre": [0, 0.7, 0.4], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0, 0.1, 1.1]
},
"0.2083": {
"pre": [0, 0.1, 1.1],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0.1, 1.1]
},
"0.5": {
"pre": [0, 0.1, 1.1],
"post": [0, 0, 0]
}
}
},
"feather": {
@@ -206,13 +462,63 @@
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0, 0, 0.61]},
"0.1667": {"pre": [0, 0, 0.61], "post": [0, 0, 0.61]},
"0.2083": {"pre": [0, 0, 0.61], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.61]},
"0.4583": {"pre": [0, 0, 0.61], "post": [0, 0, 0.61]},
"0.5": {"pre": [0, 0, 0.61], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 1.1]
},
"0.2083": {
"pre": [0, 0, 1.1],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 1.1]
},
"0.5": {
"pre": [0, 0, 1.1],
"post": [0, 0, 0]
}
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0, -0.3, -0.1]
},
"0.2083": {
"pre": [0, -0.3, -0.1],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, -0.3, -0.1]
},
"0.5": {
"pre": [0, -0.3, -0.1],
"post": [0, 0, 0]
}
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.sneasler.cry"
}
}
},
"animation.sneasler.item_hold": {
"loop": true,
"bones": {
"arm_claw_back_right": {
"rotation": [0, 0, -45]
},
"arm_claw_middle_right": {
"rotation": [0, 0, -45]
},
"arm_claw_front_right": {
"rotation": [0, 0, -45]
}
}
}
@@ -7,8 +7,8 @@
"texture_width": 256,
"texture_height": 128,
"visible_bounds_width": 10,
"visible_bounds_height": 5,
"visible_bounds_offset": [0, 1.5, 0]
"visible_bounds_height": 6,
"visible_bounds_offset": [0, 2, 0]
},
"bones": [
{
@@ -20,7 +20,7 @@
"parent": "charizard",
"pivot": [0, 0, -1],
"locators": {
"root": [0, 0, 0]
"root": [0, 0, -1]
}
},
{
@@ -28,7 +28,7 @@
"parent": "charizard",
"pivot": [0, 41, -1],
"locators": {
"top": [0, 41, 0]
"top": [0, 41, -1]
}
},
{
@@ -116,7 +116,8 @@
{
"name": "head_correction",
"parent": "head",
"pivot": [0, 43.5, -0.5]
"pivot": [0, 43.5, -0.5],
"rotation": [-95, 0, 0]
},
{
"name": "head_ai",
@@ -127,20 +128,15 @@
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 43.5, -0.5],
"rotation": [95, 0, 0],
"cubes": [
{"origin": [-3.5, 41.5, -2], "size": [7, 7, 5], "uv": [48, 0]},
{"origin": [-3.5, 41.5, -4], "size": [7, 4, 2], "uv": [95, 64]}
{"origin": [-3.5, 41.5, -4], "size": [7, 4, 2], "uv": [95, 64]},
{"origin": [-2.5, 48, -2], "size": [5, 5, 2], "inflate": 0.02, "uv": [37, 31]},
{"origin": [-2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [-2, 52.51777, -2], "rotation": [45, 0, 15], "uv": [43, 42]},
{"origin": [2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [2, 52.51777, -2], "rotation": [45, 0, -15], "uv": [41, 42]}
]
},
{
"name": "item_hat",
"parent": "head_angle",
"pivot": [0, 45, 3],
"rotation": [-90, 0, 0],
"locators": {
"item_hat": [0, 45, 3]
}
},
{
"name": "locator_head",
"parent": "head_angle",
@@ -150,51 +146,59 @@
"head": [0, 46.5, 3]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 53.75, -0.25],
"rotation": [-90, 0, 0],
"locators": {
"face": [0, 53.75, -0.25]
}
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 48.5, 0.5],
"rotation": [-90, 0, 0],
"locators": {
"item_face": [0, 48.5, 0.5]
}
},
{
"name": "locator_mouth",
"parent": "head_angle",
"pivot": [0, 45.75, -2],
"pivot": [0, 48.75, -3],
"rotation": [-90, 0, 0],
"locators": {
"mouth": [0, 45.75, -2],
"special": [0, 45.75, -2]
"mouth": [0, 48.75, -3]
}
},
{
"name": "eyes",
"name": "locator_special_attack",
"parent": "head_angle",
"pivot": [0, -3.5, 1.5]
"pivot": [0, 48.75, -3],
"rotation": [-90, 0, 0],
"locators": {
"special_attack": [0, 48.75, -3]
}
},
{
"name": "locator_jaw_upper",
"parent": "head_angle",
"pivot": [0, 51.75, -2.25],
"rotation": [-90, 0, 0],
"locators": {
"jaw1": [0, 51.75, -2.25]
}
},
{
"name": "brow",
"parent": "eyes",
"parent": "head_angle",
"pivot": [0, 48.275, 1.765],
"cubes": [
{"origin": [-2.5, 48.55, 1], "size": [5, 0, 1], "uv": [0, 14]},
{"origin": [-3.5, 47.5, 1.53], "size": [7, 1, 1], "inflate": 0.04, "uv": [0, 12]}
]
},
{
"name": "eye",
"parent": "head_angle",
"pivot": [0, -3.5, 1.5]
},
{
"name": "locator_face",
"parent": "eye",
"pivot": [0, 53.75, -0.25],
"rotation": [-90, 0, 0],
"locators": {
"face": [0, 53.75, -0.25]
}
},
{
"name": "eye_right",
"parent": "eyes",
"parent": "eye",
"pivot": [-2.75, 47.75, 0.875],
"cubes": [
{"origin": [-3.5, 47.5, 0], "size": [2, 1, 2], "inflate": 0.01, "uv": [106, 36]},
@@ -222,7 +226,7 @@
},
{
"name": "eye_left",
"parent": "eyes",
"parent": "eye",
"pivot": [2.75, 47.75, 0.875],
"cubes": [
{"origin": [1.5, 47.5, 0], "size": [2, 1, 2], "inflate": 0.01, "uv": [44, 82]},
@@ -251,91 +255,6 @@
{"origin": [2.41, 46.4, 0.5], "size": [1, 1, 1], "inflate": 0.03, "uv": [39, 86]}
]
},
{
"name": "muzzle",
"parent": "head_angle",
"pivot": [-3, 48.5, -2],
"cubes": [
{"origin": [-2.5, 48, -2], "size": [5, 5, 2], "inflate": 0.02, "uv": [37, 31]},
{"origin": [-2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [-2, 52.51777, -2], "rotation": [45, 0, 15], "uv": [43, 42]},
{"origin": [2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [2, 52.51777, -2], "rotation": [45, 0, -15], "uv": [41, 42]}
]
},
{
"name": "locator_jaw_upper",
"parent": "muzzle",
"pivot": [0, 51.75, -2.25],
"rotation": [-90, 0, 0],
"locators": {
"jaw1": [0, 51.75, -2.25]
}
},
{
"name": "nose",
"parent": "muzzle",
"pivot": [0, 53, 0],
"rotation": [-40, 0, 0],
"cubes": [
{"origin": [-2.5, 51.36698, -1.67861], "size": [5, 2, 2], "inflate": 0.03, "uv": [48, 12]},
{"origin": [-2, 53.40698, -1.17861], "size": [4, 0, 1], "uv": [0, 15]}
]
},
{
"name": "jaw",
"parent": "head_angle",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-3.5, 45.5, -4], "size": [7, 3, 2], "inflate": 0.01, "uv": [76, 20]}
]
},
{
"name": "jaw2",
"parent": "jaw",
"pivot": [0, 48.5, -4],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-2, 48.49, -4], "size": [4, 4, 2], "uv": [0, 51]},
{"origin": [-1.5, 48.5, -2], "size": [3, 4, 0], "uv": [90, 0]},
{"origin": [1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [1.5, 52.52782, -2], "rotation": [45, 0, -7.5], "uv": [37, 39]},
{"origin": [-1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [-1.5, 52.52782, -2], "rotation": [45, 0, 7.5], "uv": [37, 38]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw2",
"pivot": [0, 51.75, -1.75],
"locators": {
"jaw2": {
"offset": [0, 51.75, -1.75],
"rotation": [-90, 0, 0]
}
}
},
{
"name": "tongue",
"parent": "jaw",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-1.5, 45.5, -2], "size": [3, 3, 0], "uv": [87, 29]}
]
},
{
"name": "tongue2",
"parent": "tongue",
"pivot": [0, 48.5, -2],
"cubes": [
{"origin": [-1, 48.5, -2], "size": [2, 2, 0], "inflate": 0.01, "uv": [46, 38]}
]
},
{
"name": "tongue3",
"parent": "tongue2",
"pivot": [0, 50.5, -2],
"cubes": [
{"origin": [-1, 50.5, -2], "size": [2, 1, 0], "uv": [37, 43]},
{"origin": [-0.5, 51.5, -2], "size": [1, 1, 0], "uv": [45, 43]}
]
},
{
"name": "horns",
"parent": "head_angle",
@@ -381,6 +300,72 @@
"horn2": [2.5, 39, 2]
}
},
{
"name": "nose",
"parent": "head_angle",
"pivot": [0, 53, 0],
"rotation": [-40, 0, 0],
"cubes": [
{"origin": [-2.5, 51.36698, -1.67861], "size": [5, 2, 2], "inflate": 0.03, "uv": [48, 12]},
{"origin": [-2, 53.40698, -1.17861], "size": [4, 0, 1], "uv": [0, 15]}
]
},
{
"name": "jaw",
"parent": "head_angle",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-3.5, 45.5, -4], "size": [7, 3, 2], "inflate": 0.01, "uv": [76, 20]}
]
},
{
"name": "jaw2",
"parent": "jaw",
"pivot": [0, 48.5, -4],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-2, 48.49, -4], "size": [4, 4, 2], "uv": [0, 51]},
{"origin": [-1.5, 48.5, -1.99], "size": [3, 4, 0], "uv": [90, 0]},
{"origin": [1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [1.5, 52.52782, -2], "rotation": [45, 0, -7.5], "uv": [37, 39]},
{"origin": [-1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [-1.5, 52.52782, -2], "rotation": [45, 0, 7.5], "uv": [37, 38]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw2",
"pivot": [0, 51.75, -1.75],
"locators": {
"jaw2": {
"offset": [0, 51.75, -1.75],
"rotation": [-90, 0, 0]
}
}
},
{
"name": "tongue",
"parent": "jaw",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-1.5, 45.5, -2], "size": [3, 3, 0], "uv": [87, 29]}
]
},
{
"name": "tongue2",
"parent": "tongue",
"pivot": [0, 48.5, -2],
"cubes": [
{"origin": [-1, 48.5, -2], "size": [2, 2, 0], "inflate": 0.01, "uv": [46, 38]}
]
},
{
"name": "tongue3",
"parent": "tongue2",
"pivot": [0, 50.5, -2],
"cubes": [
{"origin": [-1, 50.5, -2], "size": [2, 1, 0], "uv": [37, 43]},
{"origin": [-0.5, 51.5, -2], "size": [1, 1, 0], "uv": [45, 43]}
]
},
{
"name": "arms",
"parent": "torso2",
@@ -418,14 +403,6 @@
{"origin": [-21.5, 22, -1.5], "size": [3, 2, 3], "inflate": 0.1, "uv": [0, 58]}
]
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-21.6, 23, 0],
"locators": {
"item": [-21.6, 23, 0]
}
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
@@ -936,14 +913,6 @@
{"origin": [0, 9.5, 58.5], "size": [0, 13, 7], "pivot": [0, 14.45, 62], "rotation": [0, 90, 0], "uv": [0, 92]}
]
},
{
"name": "locator_fire",
"parent": "fire2",
"pivot": [0, 11, 62],
"locators": {
"fire": [0, 11, 62]
}
},
{
"name": "legs",
"parent": "body",
@@ -976,10 +945,9 @@
{
"name": "locator_foot_primary",
"parent": "foot_right",
"pivot": [-9, 1.5, -5],
"rotation": [90, 0, 0],
"pivot": [-9, 1.5, -7],
"locators": {
"foot_primary": [-9, 1.5, -5]
"foot_primary": [-9, 1.5, -7]
}
},
{
@@ -1041,10 +1009,9 @@
{
"name": "locator_foot_secondary",
"parent": "foot_left",
"pivot": [9, 1.5, -5],
"rotation": [90, 0, 0],
"pivot": [9, 1.5, -7],
"locators": {
"foot_secondary": [9, 1.5, -5]
"foot_secondary": [9, 1.5, -7]
}
},
{

Some files were not shown because too many files have changed in this diff Show More