Compare commits

...
Author SHA1 Message Date
jackowes ef79cf79e3 camera fixes 2026-10-25 20:39:05 -05:00
jackowes 2b0128aed0 Port spiderpig board/climb work onto main 2026-10-25 20:28:36 -05:00
Polymeta c9d148ec9c bump showdown build and changelog
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-26 00:41:23 +00:00
Polymeta e611bf4a77 Merge branch 'fix-missing-recipe-book-data' into 'main'
Fixed Cooking Pot recipe book tabs and entries on Fabric

See merge request cable-mc/cobblemon!2510
2026-10-26 00:37:47 +00:00
Polymeta 8093822140 Merge branch 'battle-selection-fix' into 'main'
Fixed a bug with battle selection.

See merge request cable-mc/cobblemon!2509
2026-10-26 00:27:00 +00:00
Fyre520 f695ec15f9 Fixed Cooking Pot recipe book tabs and entries on Fabric 2026-10-26 02:01:15 +05:30
Deltric 1f6c791ce6 Fixed a bug with battle selection. 2026-10-25 14:24:44 -04:00
Polymeta 570805fdf1 Merge branch 'structure-tags-for-spawning' into 'main'
Structure Spawn Tags

See merge request cable-mc/cobblemon!2508
2026-10-25 16:53:38 +00:00
dhi_holo ddecb08bc7 Edit is_illager_structure.json 2026-10-26 00:21:36 +10:00
Hiroku 4d7cfcdf61 Added q.target_fainted to MoveInstruction 2026-10-25 11:11:52 +10:00
Hiroku e56dd6ef64 snap it back on 2026-10-25 10:43:01 +10:00
Hiroku ffe005511d but what would snapshot look like when it's false? 2026-10-25 10:03:22 +10:00
Hiroku 1e634a20b8 Merge remote-tracking branch 'origin/lang-updates' 2026-10-25 09:57:49 +10:00
Polymeta f9f4745e93 Merge branch 'implement_pokemon' into 'main'
Some recent riding stuff adjustments

See merge request cable-mc/cobblemon!2506
2026-10-24 16:23:07 +00:00
Kenji_64 c700674289 Fearow animations updated (again) and added all placeholders I made to the changelog 2026-10-24 18:05:05 +02:00
Kenji_64 c4f0032eee Fixed Squawkabilly's missing toe 2026-10-24 15:24:17 +02:00
Kenji_64 d92986016b Adjusted Fearow's ride stats further 2026-10-24 02:12:39 +02:00
Kenji_64 ab57e01242 Fearow is now rideable with temporary animations 2026-10-24 01:46:41 +02:00
Kenji_64 0da1c740a4 Adjusted Altaria ride stats 2026-10-24 01:44:26 +02:00
Kenji_64 a7979aa80c Adjusted Togekiss ride stats. Changed style from jet to bird 2026-10-24 01:44:10 +02:00
Polymeta 59804a4e08 rescrape spawns and drops
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-23 23:36:25 +01:00
Polymeta 072c67acad Merge branch 'implement_pokemon' into 'main'
implement_pokemon

See merge request cable-mc/cobblemon!2496
2026-10-23 22:30:54 +00:00
ewwww 60bbe221de tweaked vikavolt's jump stat 2026-10-23 17:51:10 -04:00
ewwww 5f06dc214b added vikavolt ride stats 2026-10-22 22:51:05 -04:00
ewwww a6607e585b changed vikavolt to bird style 2026-10-22 21:45:56 -04:00
Gitoido Okaski 20584f4507 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2026-10-23 01:02:35 +03:00
Kenji_64andGitoido Okaski 9660f1f724 Fixed Appletun having a green tongue. (Likely from food coloring...) 2026-10-23 00:31:07 +03:00
Kenji_64andGitoido Okaski c8cbace800 Fixed Fearow's model being messed up and added the head_ai back 2026-10-23 00:31:07 +03:00
Kenji_64andGitoido Okaski a616a24923 Fixed Swampert's weird head_ai 2026-10-23 00:31:07 +03:00
Gitoido Okaski 12035dd589 chore: mudkip animation call fix, resolver orderings streamlined 2026-10-23 00:31:07 +03:00
Kenji_64andGitoido Okaski 9627b80b01 Added Ninetales + alolan placeholder animations 2026-10-23 00:31:07 +03:00
Kenji_64andGitoido Okaski 4e9cecc854 Converted Squawkabilly's poser to JSON and added placeholder animations 2026-10-23 00:31:06 +03:00
ewwwwandGitoido Okaski 9d4b19b185 vikavolt can be mounted (stat placeholders) 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski aee96d06aa Made Pichu shut up in its sleep 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski 23e3c585f7 Wave 2 of profile adjustments 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski c22a88079f Added Fearow placeholders and fixed its neck (also adjusted Swampert placeholder) 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski 2225402082 Added transparency to Vikavolt 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski 9197207431 Implemented Magby and Magmar animations 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski 47c7f7079c Added placeholder animations to Mudkip, Marshtomp, Swampert and Spearow 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski eb0c1dddfd Scaled down a huge lot of small Pokémon's profiles and fixed some that were off over all 2026-10-23 00:31:06 +03:00
Kenji_64andGitoido Okaski e3dbfe6ff8 Added Eerie Spell activate and Hospitality lang (Hospitality's text does not work properly atm due to a Doubles bug) 2026-10-23 00:31:06 +03:00
whatsyandGitoido Okaski fac207f36b Revert "Rescrape drops"
This reverts commit 6a7d5d2133.
2026-10-23 00:31:06 +03:00
ewwwwandGitoido Okaski 379e794848 removed igglybuff, jigglypuff, and wigglytuff's rights to float 2026-10-23 00:31:06 +03:00
ewwwwandGitoido Okaski 9081a4b131 added water shuriken fx 2026-10-23 00:31:06 +03:00
ewwwwandGitoido Okaski dc6d75b8ee sped up cacnea and hippowdon's walk speed 2026-10-23 00:31:06 +03:00
ewwwwandGitoido Okaski bb297a4448 fixed t-posing archeops during air_cry 2026-10-23 00:31:06 +03:00
whatsyandGitoido Okaski a93922c438 Rescrape drops 2026-10-23 00:31:06 +03:00
Kenji_64 f7d21c80d7 Fixed Appletun having a green tongue. (Likely from food coloring...) 2026-10-22 23:16:45 +02:00
Kenji_64 9248d26fd4 Fixed Fearow's model being messed up and added the head_ai back 2026-10-22 23:03:50 +02:00
dhi_holo b5ac54cd16 Tweaks to prepare for Scrapes 2026-10-21 14:22:17 +10:00
dhi_holo dc703e67f7 Merge branch 'main' into structure-tags-for-spawning 2026-10-21 14:01:10 +10:00
Kenji_64 0930721865 Fixed Swampert's weird head_ai 2026-10-19 16:34:31 +02:00
Gitoido Okaski 644ff1772e chore: mudkip animation call fix, resolver orderings streamlined 2026-10-19 16:56:42 +03:00
Kenji_64 3c7e0bebb6 Added Ninetales + alolan placeholder animations 2026-10-19 15:44:42 +02:00
Kenji_64 0c0eea3876 Converted Squawkabilly's poser to JSON and added placeholder animations 2026-10-19 15:44:20 +02:00
ewwww 5535140bb7 vikavolt can be mounted (stat placeholders) 2026-10-19 03:37:39 -04:00
Polymeta f9dd1448e5 Merge branch 'item-2072' into 'main'
Added tab completion for the alpha property and three missing property aliases

Closes #2072

See merge request cable-mc/cobblemon!2388
2026-10-18 22:33:30 +00:00
Gitoido ecf5d57ad2 chore: resolve conflicts
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/pokemon/properties/PropertiesCompletionProvider.kt
2026-10-18 22:16:27 +00:00
Polymeta 8663888abc Merge branch 'item-2013' into 'main'
Fixed GUI Pokémon cries playing on the Master category instead of Friendly Creatures

Closes #2013

See merge request cable-mc/cobblemon!2389
2026-10-18 22:14:04 +00:00
Polymeta f452cd9a05 Merge branch 'fix/ride-interact-checks' into 'main'
fix: stricter riding checks on server side

Closes #2124

See merge request cable-mc/cobblemon!2499
2026-10-18 22:12:19 +00:00
Kiritiop 4fe9cd7fd6 Fixed GUI pokemon cries using the Master volume slider instead of Friendly Creatures, added a new file to prevent code duplication. Credit to Gitoido 2026-10-18 13:19:07 -04:00
Kenji_64 9b0ca1c16b Made Pichu shut up in its sleep 2026-10-18 18:46:52 +02:00
Kenji_64 052ff59f57 Wave 2 of profile adjustments 2026-10-18 18:46:15 +02:00
Kenji_64 40e5ef1c46 Added Fearow placeholders and fixed its neck (also adjusted Swampert placeholder) 2026-10-18 18:45:31 +02:00
Kenji_64 5025977d23 Added transparency to Vikavolt 2026-10-18 18:44:22 +02:00
Kenji_64 922006afe7 Implemented Magby and Magmar animations 2026-10-18 16:14:45 +02:00
Kenji_64 46cc7cb04d Added placeholder animations to Mudkip, Marshtomp, Swampert and Spearow 2026-10-18 15:48:35 +02:00
Kenji_64 fa3e3bbb1b Scaled down a huge lot of small Pokémon's profiles and fixed some that were off over all 2026-10-18 15:47:46 +02:00
Kenji_64 afbdcce337 Added Eerie Spell activate and Hospitality lang (Hospitality's text does not work properly atm due to a Doubles bug) 2026-10-18 15:46:19 +02:00
Gitoido Okaski 2c1d11ed11 chore: remove duplicate check that was accounted for earlier 2026-10-18 15:29:35 +03:00
Gitoido Okaski b88adf0479 fix: stricter riding checks on server side 2026-10-18 15:21:09 +03:00
Polymeta b1066671f5 Merge branch 'quick-fix' into 'main'
Flowerbed Clearning jigsaw fix, dripstone oasis jigsaw removal

See merge request cable-mc/cobblemon!2497
2026-10-18 12:09:48 +00:00
Polymeta 387e85d4ad Merge branch 'fix/preset-conditions-mergers' into 'main'
fix: Some spawn conditions merge minHeight/Depth data into max instead

Closes #2111

See merge request cable-mc/cobblemon!2498
2026-10-18 12:07:55 +00:00
Nico MerenqandWeblate 1fa113f5ac Translated using Weblate (Russian)
Currently translated at 84.8% (8137 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ru/
2026-10-18 11:56:30 +00:00
Gitoido Okaski 77ab58d823 fix: spawn condition mergers writing minHeight/depth into maxHeight/depth instead 2026-10-18 14:14:28 +03:00
Slippy 1a9e736d8b Flowerbed Clearning jigsaw fix, dripstone oasis jigsaw removal 2026-10-18 00:11:56 -05:00
whatsy f680682f61 Revert "Rescrape drops"
This reverts commit 6a7d5d2133.
2026-10-17 22:51:02 -04:00
whatsy 4d93d1244d Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2026-10-17 22:40:25 -04:00
whatsy 6a7d5d2133 Rescrape drops 2026-10-17 22:40:13 -04:00
ewwww 98397cd1da removed igglybuff, jigglypuff, and wigglytuff's rights to float 2026-10-17 21:57:59 -04:00
ewwww fc5a610394 added water shuriken fx 2026-10-17 20:37:00 -04:00
ewwww 504df5d998 sped up cacnea and hippowdon's walk speed 2026-10-17 20:16:26 -04:00
ewwww 3b4d3ebf50 fixed t-posing archeops during air_cry 2026-10-17 20:01:56 -04:00
Hiroku aa39c1906e Merge branch 'implement_pokemon' into 'main'
implement_pokemon

See merge request cable-mc/cobblemon!2495
2026-10-17 23:48:54 +00:00
ewwww 2e460e2ca2 fixed floating frogadier 2026-10-17 19:43:44 -04:00
Polymeta a07ff7f442 Merge branch 'implement_pokemon' into 'main'
implement_pokemon

See merge request cable-mc/cobblemon!2494
2026-10-17 23:37:18 +00:00
Polymeta 5374569ea1 [skip-ci] tidy up changelog
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-18 00:15:37 +01:00
Polymeta af9c1196bf youre meant to be looking the other way
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-18 00:08:51 +01:00
Polymeta 09d5543469 Merge branch 'fix/haters-gonna-hate-properly' into 'main'
fix: Anger should be directed at proper target

Closes #2112

See merge request cable-mc/cobblemon!2492
2026-10-17 23:03:41 +00:00
ewwww 49e4dd0298 helioptile & heliolisk cries 2026-10-17 19:01:46 -04:00
Polymeta c8e408c50a actually copy components when building up evolution displays
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-17 23:57:05 +01:00
Gitoido Okaski e8a0467643 chore: move coercion at class variable level 2026-10-18 01:17:07 +03:00
Gitoido Okaski 2dd0b66b83 chore: remove duplicate i18n key 2026-10-18 01:04:29 +03:00
Gitoido Okaski 68374017e1 chore: changelog 2026-10-18 01:04:29 +03:00
ewwww 120520f51d vikavolt animations + cries for grubbin, charjabug, & vikavolt 2026-10-17 18:01:25 -04:00
Gitoido Okaski e8dea9773a feat: make sure zangoose and zeviper 100% hate each other 2026-10-18 00:59:40 +03:00
Gitoido Okaski 7b31e6bcc4 feat: make sure hate task uses new values from config and gamerule 2026-10-18 00:59:10 +03:00
Gitoido Okaski c6ffca639f feat: pokemon predation chance config i18n 2026-10-18 00:58:40 +03:00
Gitoido Okaski c491a1f7ca feat: introduce pokemon predation chance config 2026-10-18 00:56:06 +03:00
Gitoido Okaski 0b333b743d feat: introduce pokemon predation gamerule 2026-10-18 00:55:54 +03:00
ewwww 95e79865e5 updated posers for fennekin & braixen 2026-10-17 16:24:40 -04:00
Gitoido Okaski 0e2860cd90 chore: import cleanup skip_ci 2026-10-17 23:14:08 +03:00
Gitoido Okaski 3259bf032c chore: changelog skip_ci 2026-10-17 23:10:15 +03:00
Gitoido OkaskiandGitoido 116205cdf1 fix: Anger should be directed at proper target 2026-10-17 20:07:18 +00:00
ewwww 43277d18dc Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2026-10-17 13:37:05 -04:00
Polymeta 86153419ee Merge branch 'implement_pokemon' into 'main'
implement_pokemon

See merge request cable-mc/cobblemon!2480
2026-10-17 17:36:00 +00:00
Gitoido Okaski 2b4d9c451c fix: Various poser/animation fixes (Wave 3.4.1) 2026-10-17 20:07:17 +03:00
Gitoido Okaski 7f0e2fa9d8 fix: Various poser/animation fixes (Wave 3.3) 2026-10-17 19:43:00 +03:00
Gitoido Okaski e165095bd5 fix: Various poser/animation fixes (Wave 3.2.1) 2026-10-17 19:38:06 +03:00
Gitoido Okaski b8708d6e10 fix: Various poser/animation fixes (Wave 3.2) 2026-10-17 19:36:25 +03:00
Kenji_64 ef536390ca Various poser/animation fixes (Wave 3.1). The rats make me crazy. 2026-10-17 18:27:28 +02:00
ewwww 28befab173 cries for combee & vespiquen 2026-10-17 12:22:20 -04:00
ewwww c142439d5b cries for wurmple, silcoon, cascoon. beautifly, & dustox 2026-10-17 12:21:49 -04:00
Jerzykv 1ca7335654 Various poser/animation fixes (Wave 3) 2026-10-17 18:18:39 +02:00
ewwww 9197d9cdcd cries for runerigus 2026-10-17 11:52:04 -04:00
ewwww f75813e64d cries for dusknoir 2026-10-17 11:45:44 -04:00
ewwww 1f617c76a4 cries for torkoal 2026-10-17 11:45:20 -04:00
ewwww ebf573aa7a cries for surskit & masquerain 2026-10-17 11:44:29 -04:00
Kenji_64 75363da470 Various poser/animation fixes (Wave 2.5) 2026-10-17 17:42:04 +02:00
ewwww cce4b932cc cries for hoppip, skiploom, & jumpluff 2026-10-17 11:41:45 -04:00
Kenji_64 0973e1ced0 Various poser/animation fixes (Wave 2) 2026-10-17 17:31:30 +02:00
Kenji_64 e7b5c84024 Various poser/animation fixes 2026-10-17 13:43:58 +02:00
ewwww 4001cc2a89 vikavolt animations + cries for grubbin, charjabug, & vikavolt 2026-10-17 06:08:31 -04:00
Polymeta 6e57d77d10 Merge branch 'More-Structure-Fixes' into 'main'
More structure fixes

See merge request cable-mc/cobblemon!2491
2026-10-16 22:54:46 +00:00
Slippy 2206d96a6e Lots of fixing 2026-10-16 14:26:55 -05:00
Slippy 33f05858f1 structure fixes for .3 2026-10-16 13:34:04 -05:00
Watuneni iteiteandWeblate 8443b88c16 Translated using Weblate (Japanese)
Currently translated at 99.0% (9500 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ja/
2026-10-16 17:12:33 +00:00
ewwww a4f204a5a3 changelog 2026-10-16 06:06:11 -04:00
ewwww 31b6be2164 applin & flapple cry updates + cries for appletun & dipplin 2026-10-16 06:06:00 -04:00
ewwww 0dbf73067b houndour & houndoom cries 2026-10-16 06:03:48 -04:00
ewwww 775703e1f5 starly, staravia, and staraptor cries 2026-10-16 06:03:20 -04:00
Polymeta bcdfef4886 Merge branch 'lights-out' into 'main'
Bye Bye Magmarizer Glow

See merge request cable-mc/cobblemon!2490
2026-10-16 06:49:58 +00:00
dhi_holo a19adb463b Bye Bye Magmarizer Glow
- Removed Dynamic Lights data from the Magmarizer item for consistency with the block
2026-10-16 16:32:05 +10:00
Gustavo PuerariandWeblate b71208299f Translated using Weblate (Portuguese (Brazil))
Currently translated at 96.7% (9276 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2026-10-15 18:07:01 +00:00
Watuneni iteiteandWeblate 136b5824b0 Translated using Weblate (Japanese)
Currently translated at 98.7% (9464 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ja/
2026-10-15 18:06:58 +00:00
Polymeta 5004edbbb6 Merge branch 'fix/party-overlay-hide-nf' into 'main'
fix: party overlay not hiding when player opens the pokedex scanner

Closes #2071

See merge request cable-mc/cobblemon!2467
2026-10-15 15:37:49 +00:00
Gitoido Okaski d8bdd6329a fix: tidy-up even more 2026-10-15 17:57:42 +03:00
Gitoido Okaski 82d56637a0 chore: method signature name 2026-10-15 17:07:28 +03:00
Gitoido Okaski 7232a43816 refactor: move and enqueue client event registration to separate fn, homogenizing behavior with common side registration 2026-10-15 17:05:50 +03:00
Gitoido Okaski 098eb7d14b chore: tidy up changelog skip-ci 2026-10-15 16:22:30 +03:00
Gitoido OkaskiandGitoido 835b70ed48 feat: AppleSkin compat for dex scanner mode 2026-10-15 13:20:53 +00:00
Gitoido 9d828a86fb fix: party overlay not hiding when player opens the pokedex scanner 2026-10-15 13:20:53 +00:00
Polymeta 910551ee70 Merge branch 'fix/berry-pots' into 'main'
fix: flower pots require some tending on neoforge

Closes #2126

See merge request cable-mc/cobblemon!2486
2026-10-15 07:17:23 +00:00
ewwww 9beee548d4 Merge branch 'main' into implement_pokemon 2026-10-15 01:30:50 -04:00
Watuneni iteiteandWeblate f9189b265f Translated using Weblate (Japanese)
Currently translated at 98.7% (9464 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ja/
2026-10-14 15:27:44 +00:00
Polymeta 6f3894f27b fix playermolang sometimes failing when they die
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-14 13:33:40 +01:00
Polymeta bbc9a5e62e Merge branch 'campfire-book-lies' into 'main'
Recipe Book Lies No More

See merge request cable-mc/cobblemon!2487
2026-10-14 11:32:52 +00:00
Gitoido Okaski 94765da04a chore: small tidy-up 2026-10-14 14:11:30 +03:00
dhi_holo 8caa82f123 Recipe Book Lies No More
Changed the icon for the misc category
2026-10-14 18:42:58 +10:00
dhi_holo 8e1fcc6f14 Structure Spawn Tags
Feel free to rename, delete, or rework any of these, it's moreso just setting the groundwork

`spawns/is_aquatic_monument` - Ocean Monuments and related structures
`spawns/is_aquatic_ruins` - Ocean Ruins and similar structures
`spawns/is_civilization` - Village and Towns tag, for anything that should spawn at any kind of village/town
`spawns/is_desert_monument` - Desert Pyramids and Temples
`spawns/is_dungeon` - Modded tag, the idea is things of the Stronghold *vibe*, but not being literal strongholds
`spawns/is_end_structure` - End Cities and related structures
`spawns/is_graveyard` - Modded tag, graveyards and crypts
`spawns/is_igloo` - just the vanilla igloo, it's me just wanting stuff in tags where it isn't yet so if some addon wants to give igloos another place they can
`spawns/is_illager_outpost` - small settlements for illagers, such as campsites and other small watchtower-like things
`spawns/is_illager_structure` - Bigger illager structures, the mansion, manors, stuff that has a sense of "infrastructure" I suppose
`spawns/is_jungle_monument` - Jungle Temples and Pyramids
`spawns/is_nether_structure` - is a structure of the Nether
`spawns/is_piglin_structure` - is a structure specifically inhabited by Piglins. Can be used to either add stuff specifically around Piglins, or to prevent things around them
`spawns/is_ruins` - Taking what we have as ruins and just applying that logic to other mods
`spawns/is_shipwreck` - not sure if we use this for spawns, but if we do this can be hooked into, if not then this could be deleted, no hassle, just felt like a logical thing to include. Is related to "surface" shipwrecks, not things like the coves
`spawns/is_witch_structure` - witch structures, like huts, villages, etc. Also added any structures that force black cat spawning, as that's used to reference to witches in the vanilla tags

Mods used within the tags so far:
https://modrinth.com/mod/dungeons-and-taverns (`nova_structures`)
A lot of https://modrinth.com/organization/nuVP8uUG mods (the Yung structure ones, usually starts as `better` and then the structure name)
https://modrinth.com/mod/enderscape
https://modrinth.com/mod/aquamirae
https://modrinth.com/mod/terralith
Will continue to investigate mods to add to these
2026-10-14 17:54:34 +10:00
Watuneni iteiteandWeblate 21c4d0233d Translated using Weblate (Japanese)
Currently translated at 98.7% (9464 of 9587 strings)

Translation: Cobblemon/Mod
Translate-URL: https://lang.cobblemon.com/projects/cobblemon/mod/ja/
2026-10-13 12:09:59 +00:00
Gitoido Okaski 131ef31492 fix: tend to the pots registration on neoforge 2026-10-13 03:38:13 +03:00
Gitoido Okaski b6b067b1d3 chore: changelog skip-ci 2026-10-13 03:35:28 +03:00
RedGenesectNinja 546f10eca7 Gave Audino its alpha eyes back 2026-10-12 19:19:05 -05:00
Kiritiop fb4aaed220 Edit CHANGELOG.md 2026-10-11 08:57:22 +00:00
Kiritiop c5e1b37ead Manual rebase 2026-10-11 08:53:30 +00:00
Kiritiop 2be9d303ea Added tab completion for the alpha property and three missing property aliases
Closes #2072
2026-10-11 08:53:30 +00:00
Kiritiop 99ac6d213a Added tab completion for the alpha property and three missing property aliases
Closes #2072
2026-10-11 08:53:30 +00:00
ewwww 6f4aae8b7d grubbin, charjabug, and vikavolt are marked as implemented 2026-10-10 23:33:06 -04:00
ewwww 01e5e74e64 snover and abomasnow are marked as implemented 2026-10-10 23:32:49 -04:00
ewwww b6565a5dee greavard and houndstone are marked as implemented 2026-10-10 23:29:38 -04:00
674 changed files with 30622 additions and 2997 deletions
+12 -27
View File
@@ -1,46 +1,31 @@
# Changelog
## [1.8.3 (MONTH xth, 2026)](#1-8-3)
## [1.8.x (MONTH xth, 2026)](#1-8-x)
### Additions
### New rideable Pokémon
### Pokémon Added
#### Generation 4
#### Generation 5
#### Generation 6
#### Generation 7
#### Generation 8
#### Generation 9
### Model updates for the following Pokémon
### Animation updates for the following Pokémon
### Changes
- Reworked spawn presets and added structure tags for spawns
### Fixes
- Fixed datapacks with item interaction evolutions that don't specify an item crashing the world on load.
- Fixed the Pokédex evolution tree crashing when a datapack's dex entry is missing an evolution's form.
- Fixed the Pokédex evolution tree crashing with a stack overflow on evolutions that loop back on themselves.
- Fixed the Pokédex evolution tree crashing when looking at a dex that is not part of the "National Dex" aggregate.
- Fixed evolution trees not building properly when a pokemon has several pokedex entries for different regions.
- Fixed form-changing evolutions sometimes resolving to the source form in the Pokédex evolution tree.
- Broken datapack evolutions are now logged and skipped in the Pokédex evolution tree instead of crashing.
- Fixed friendship booster items not being recognised as such
- Fixed conflicts with other mods that would make use of recipe books in certain ways (Farmer's Delight Cooking Pot)
- Fixed Pokémon battles stalling when a sidemod cancels the `THROWN_POKEBALL_HIT` hit event
- Fixed choice feature tab completion in `spawnpokemon/pokegive/pokeedit` commands
- Fixed blank Cooking Pot recipe book entries and missing tabs on Fabric.
- Fixed Minior's "Shields Down" ability not working as intended
### Developer
- Bumped NeoForge to `21.1.195` to get access to MixinExtras `0.5` and the expressions annotation
### Molang & Datapacks
- Fixed `q.pokemon.nature` returning class instance instead of proper string value (`cobblemon:adamant`)
- Fixed `q.entity.is_looking_at` result being always `1` for whatever entity passed as target
- Added `q.target_fainted` function to move action effects that checks if any opponents fainted from the move.
### Particles
#### New Move Animations
### Localization
- Updated translations for:
- Updated translations for:
+107
View File
@@ -0,0 +1,107 @@
# Changelog
## [1.8.3 (October 25th, 2026)](#1-8-3)
### Additions
- Added compatability with AppleSkin.
### New Rideable Pokémon
- Vikavolt
- Fearow
### Particles
## New Move Animations
- Water Shuriken
### Cries added/updated for the following Pokémon
- Hoppip
- Skiploom
- Jumpluff
- Houndour
- Houndoom
- Wurmple
- Silcoon
- Beautifly
- Cascoon
- Dustox
- Surskit
- Masquerain
- Torkoal
- Starly
- Staravia
- Staraptor
- Combee
- Vespiquen
- Dusknoir
- Helioptile
- Heliolisk
- Grubbin
- Charjabug
- Vikavolt
- Applin (updated)
- Flapple (updated)
- Appletun
- Runerigus
- Dipplin
### Animation updates for the following Pokémon
- Vikavolt
- Magby
- Magmar
- Ninetales (+ Alolan)
- Spearow
- Fearow
- Squawkabilly
- Mudkip
- Marshtomp
- Swampert
### Changes
- Changed the Misc icon in the Campfire Pot Recipe Book to Health Candy.
- Moved EXP Candies from the Medicine recipe book category to the Misc category.
- Removed Dynamic Lights data from the Magmarizer item for consistency with the block.
- Added `doPokemonPredation` game rule, which controls aggressiveness of Pokémon with the `hate_entity` brain task defined.
- Added `predation_chance` server config value, which controls the possibility of attacking the hated entity found in `hate_entity` brain tasks.
- Prehistoric Eroded Pillar generates slightly more frequently.
- Togekiss was changed from a jet-style mount to bird-style.
### Fixes
- Fixed datapacks with item interaction evolutions that don't specify an item crashing the world on load.
- Fixed the Pokédex evolution tree crashing when a datapack's dex entry is missing an evolution's form.
- Fixed the Pokédex evolution tree crashing with a stack overflow on evolutions that loop back on themselves.
- Fixed the Pokédex evolution tree crashing when looking at a dex that is not part of the "National Dex" aggregate.
- Fixed some display names in the Pokédex evolution tree having unintended font colours.
- Fixed evolution trees not building properly when a Pokémon has several Pokédex entries for different regions.
- Fixed form-changing evolutions sometimes resolving to the source form in the Pokédex evolution tree.
- Broken datapack evolutions are now logged and skipped in the Pokédex evolution tree instead of crashing.
- Fixed the `alpha` property having no tab completion in commands such as `/pokespawn`, `/pokegive` and `/pokeedit`, and added the missing `dmax_level`, `gmax_factor` and `tradable` aliases to tab completion.
- Fixed friendship booster items not being recognised as such.
- Fixed conflicts with other mods that would make use of recipe books in certain ways (Farmer's Delight Cooking Pot).
- Fixed Pokémon battles stalling when a sidemod cancels the `THROWN_POKEBALL_HIT` hit event.
- Fixed choice feature tab completion in `spawnpokemon/pokegive/pokeedit` commands.
- Fixed MoLang that's targeting players intermittedly failing when they have died, requiring them to relog.
- Fixed a NeoForge bug where none of the Cobblemon plants/berries could be placed into pots.
- Fixed party overlay not hiding when the player opens the Pokédex scanner.
- Fixed `hate_entity` task focusing on its own entity, therefore enabling deadly warfare between Zangoose and Seviper.
- Prehistoric Frozen Pond, Prehistoric Frozen Spike, and Prehistoric Lush Den now actually generate (oops).
- Fixed Frogadier floating in its `battle_idle` animation.
- Fixed absence or incorrect mergers in spawning conditions, causing the max height/depth of conditions to use the min value instead.
- Added stricter riding checks on server side to prevent possible packet forgery when a player tries to ride Pokémon.
- Fixed Pokémon cries and animation sounds played from GUIs, such as the starter selection screen and the Pokédex, being tied to the Master volume slider instead of Friendly Creatures.
- Fixed Archeops T-posing during its `air_cry` animation.
### Developer
- Bumped NeoForge to `21.1.195` to get access to MixinExtras `0.5` and the expressions annotation.
- New Platform Event `PLAYER_RESPAWN` which is fired when a player respawns (either through death or returning from the end).
- Platform Events `SERVER_PLAYER_TICK_PRE` and `SERVER_PLAYER_TICK_POST` no longer fire when the player is dead.
- It is now tied much closer to the actual entity rather than the player or their connection.
### Molang & Datapacks
- Fixed `q.pokemon.nature` returning class instance instead of proper string value (`cobblemon:adamant`).
- Fixed `q.entity.is_looking_at` result being always `1` for whatever entity passed as the target parameter.
- Added hate chance optional parameter to `hate_entity` task. `1.0` will make an entity always attack the target.
### Localization
- Updated translations for:
- Russian
- Japanese
- Brazilian Portuguese
@@ -75,9 +75,10 @@ public abstract class LivingEntityMixin extends Entity implements OrientationCon
public @NotNull HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
Entity vehicle = this.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity && pokemonEntity.getDelegate() instanceof PokemonClientDelegate delegate) {
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
Seat seat = pokemonEntity.getSeats().get(seatIndex);
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
// Passenger order isn't seat order, so look the seat up directly
Seat seat = pokemonEntity.getSeatForPassenger(this);
MatrixWrapper locator = seat != null ? delegate.getLocatorStates().get(seat.getLocator()) : null;
if (locator == null) return super.pick(hitDistance, partialTicks, hitFluids);
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
@@ -99,7 +100,8 @@ public abstract class LivingEntityMixin extends Entity implements OrientationCon
@Unique
private Vec3 cobblemon$getEyePosition(float partialTicks, PokemonEntity pokemonEntity, Vec3 locatorOffset) {
OrientationController controller = this.getOrientationController();
// The ride owns the orientation, the passenger's own controller is never active
OrientationController controller = ((OrientationControllable) pokemonEntity).getOrientationController();
float currEyeHeight = this.getEyeHeight();
Vec3 offset = locatorOffset.add(pokemonEntity.position());
@@ -107,7 +109,7 @@ public abstract class LivingEntityMixin extends Entity implements OrientationCon
Quaternionf orientation = controller.getRenderOrientation(partialTicks);
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(new Vector3f(0f, currEyeHeight - (this.getBbHeight() / 2), 0f)));
offset.add(rotatedEyeHeight);
offset = offset.add(rotatedEyeHeight);
}
return offset;
@@ -69,7 +69,7 @@ public abstract class ClientRecipeBookMixin {
value = "INVOKE",
target = "Lcom/google/common/collect/ImmutableMap;copyOf(Ljava/util/Map;)Lcom/google/common/collect/ImmutableMap;"
))
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci, @Local(name = "map2") Map<RecipeBookCategories, List<RecipeCollection>> map2) {
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci, @Local(ordinal = 1) Map<RecipeBookCategories, List<RecipeCollection>> map2) {
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
}
}
@@ -50,11 +50,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map;
import java.util.Objects;
@Mixin(LocalPlayer.class)
public abstract class LocalPlayerMixin extends AbstractClientPlayer implements OrientationControllable, DoubleJump {
@Unique Matrix3f cobblemon$lastOrientation;
@Unique int cobblemon$lastOrientationVehicleId = -1;
@Unique float cobblemon$lastRideXRot;
@Unique float cobblemon$lastRideYRot;
@@ -81,9 +83,18 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
private void cobblemon$updateRotationMatrixPassenger(CallbackInfo ci) {
if (!(this.getVehicle() instanceof OrientationControllable controllableVehicle)) return;
var vehicleController = controllableVehicle.getOrientationController();
if (!vehicleController.isActive() || vehicleController.getOrientation() == cobblemon$lastOrientation) return;
cobblemon$lastOrientation = vehicleController.getOrientation() != null ? new Matrix3f(vehicleController.getOrientation()) : null;
CobblemonNetwork.INSTANCE.sendToServer(new ServerboundUpdateOrientationPacket(this.getVehicle().getId(), vehicleController.getOrientation()));
if (!vehicleController.isActive()) {
// Forget the last sent value so the next ride always gets its first orientation sent
cobblemon$lastOrientation = null;
return;
}
var orientation = vehicleController.getOrientation();
var vehicleId = this.getVehicle().getId();
// Compare by value, the stored one is a copy so a reference check never matches
if (vehicleId == cobblemon$lastOrientationVehicleId && Objects.equals(orientation, cobblemon$lastOrientation)) return;
cobblemon$lastOrientation = orientation != null ? new Matrix3f(orientation) : null;
cobblemon$lastOrientationVehicleId = vehicleId;
CobblemonNetwork.INSTANCE.sendToServer(new ServerboundUpdateOrientationPacket(vehicleId, orientation));
}
@Inject(method = "rideTick", at = @At("HEAD"))
@@ -20,14 +20,14 @@ import org.spongepowered.asm.mixin.injection.At;
@Mixin(RecipeBookComponent.class)
public class RecipeBookComponentMixin {
@Definition(id = "recipeBookCategories", local = @Local(name = "recipeBookCategories"))
@Definition(id = "recipeBookCategories", local = @Local(type = RecipeBookCategories.class))
@Definition(id = "FURNACE_SEARCH", field = "Lnet/minecraft/client/RecipeBookCategories;FURNACE_SEARCH:Lnet/minecraft/client/RecipeBookCategories;")
@Expression("recipeBookCategories != FURNACE_SEARCH")
@ModifyExpressionValue(
method = "updateTabs",
at = @At(value = "MIXINEXTRAS:EXPRESSION")
)
private boolean notCookingPotSearch(boolean original, @Local(name = "recipeBookCategories") RecipeBookCategories recipeBookCategories) {
private boolean notCookingPotSearch(boolean original, @Local RecipeBookCategories recipeBookCategories) {
return original && recipeBookCategories != CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory();
}
}
@@ -38,6 +38,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Entity.class)
public abstract class EntityMixin {
// How far the clientsent ride eye can sit from the players
@Unique private static final double COBBLEMON$MAX_RIDE_EYE_OFFSET = 3.0;
@Shadow @Nullable public abstract Entity getVehicle();
@Inject(method = "updateInWaterStateAndDoWaterCurrentPushing", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/Entity;wasTouchingWater:Z", ordinal = 1), cancellable = true)
@@ -91,6 +94,9 @@ public abstract class EntityMixin {
if (vehicleController == null) return;
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
Vec3 vanillaEyePos = new Vec3(player.getX(), player.getEyeY(), player.getZ());
double maxSqr = COBBLEMON$MAX_RIDE_EYE_OFFSET * COBBLEMON$MAX_RIDE_EYE_OFFSET;
if (customEyePos == null || !(customEyePos.distanceToSqr(vanillaEyePos) <= maxSqr)) return;
cir.setReturnValue(customEyePos);
}
@@ -260,6 +260,9 @@ object Cobblemon {
RequestManager.onLogoff(it.player)
serverPlayerStructs.remove(it.player.uuid)
}
PlatformEvents.PLAYER_RESPAWN.subscribe {
serverPlayerStructs.remove(it.player.uuid)
}
PlatformEvents.PLAYER_DEATH.subscribe {
PCLinkManager.removeLink(it.player.uuid)
battleRegistry.getBattleByParticipatingPlayer(it.player)?.stop()
@@ -845,54 +845,35 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val PEP_UP_FLOWER = this.create("pep_up_flower", FlowerBlock(MobEffects.LEVITATION, 10F, BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().instabreak().sound(SoundType.GRASS).offsetType(BlockBehaviour.OffsetType.XZ).pushReaction(PushReaction.DESTROY)))
@JvmField
val POTTED_PEP_UP_FLOWER = this.create("potted_pep_up_flower", BlocksInvoker.createFlowerPotBlock(PEP_UP_FLOWER))
@JvmField
val HEARTY_GRAINS = this.create("hearty_grains", HeartyGrainsBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak()))
@JvmField
val GALARICA_NUT_BUSH = this.create("galarica_nut_bush", NutBushBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().sound(SoundType.SWEET_BERRY_BUSH).pushReaction(PushReaction.DESTROY)))
@JvmField
val POTTED_RED_APRICORN_SAPLING = this.create("potted_red_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(RED_APRICORN_SAPLING))
@JvmField
val POTTED_YELLOW_APRICORN_SAPLING = this.create("potted_yellow_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(YELLOW_APRICORN_SAPLING))
@JvmField
val POTTED_GREEN_APRICORN_SAPLING = this.create("potted_green_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(GREEN_APRICORN_SAPLING))
@JvmField
val POTTED_BLUE_APRICORN_SAPLING = this.create("potted_blue_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(BLUE_APRICORN_SAPLING))
@JvmField
val POTTED_PINK_APRICORN_SAPLING = this.create("potted_pink_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(PINK_APRICORN_SAPLING))
@JvmField
val POTTED_BLACK_APRICORN_SAPLING = this.create("potted_black_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(BLACK_APRICORN_SAPLING))
@JvmField
val POTTED_WHITE_APRICORN_SAPLING = this.create("potted_white_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(WHITE_APRICORN_SAPLING))
@JvmField
val POTTED_SACCHARINE_SAPLING = this.create("potted_saccharine_sapling", BlocksInvoker.createFlowerPotBlock(SACCHARINE_SAPLING))
@JvmField
val RED_MINT_LEAF_LITTER = this.mintLitter("red_mint_leaf_litter", MapColor.COLOR_RED)
@JvmField
val POTTED_RED_MINT = this.pottedPlant("potted_red_mint", RED_MINT_LEAF_LITTER)
val POTTED_RED_MINT = this.flowerPot("potted_red_mint", RED_MINT_LEAF_LITTER)
@JvmField
val BLUE_MINT_LEAF_LITTER = this.mintLitter("blue_mint_leaf_litter", MapColor.COLOR_BLUE)
@JvmField
val POTTED_BLUE_MINT = this.pottedPlant("potted_blue_mint", BLUE_MINT_LEAF_LITTER)
val POTTED_BLUE_MINT = this.flowerPot("potted_blue_mint", BLUE_MINT_LEAF_LITTER)
@JvmField
val CYAN_MINT_LEAF_LITTER = this.mintLitter("cyan_mint_leaf_litter", MapColor.COLOR_CYAN)
@JvmField
val POTTED_CYAN_MINT = this.pottedPlant("potted_cyan_mint", CYAN_MINT_LEAF_LITTER)
val POTTED_CYAN_MINT = this.flowerPot("potted_cyan_mint", CYAN_MINT_LEAF_LITTER)
@JvmField
val PINK_MINT_LEAF_LITTER = this.mintLitter("pink_mint_leaf_litter", MapColor.COLOR_PINK)
@JvmField
val POTTED_PINK_MINT = this.pottedPlant("potted_pink_mint", PINK_MINT_LEAF_LITTER)
val POTTED_PINK_MINT = this.flowerPot("potted_pink_mint", PINK_MINT_LEAF_LITTER)
@JvmField
val GREEN_MINT_LEAF_LITTER = this.mintLitter("green_mint_leaf_litter", MapColor.COLOR_GREEN)
@JvmField
val POTTED_GREEN_MINT = this.pottedPlant("potted_green_mint", GREEN_MINT_LEAF_LITTER)
val POTTED_GREEN_MINT = this.flowerPot("potted_green_mint", GREEN_MINT_LEAF_LITTER)
@JvmField
val WHITE_MINT_LEAF_LITTER = this.mintLitter("white_mint_leaf_litter", MapColor.SNOW)
@JvmField
val POTTED_WHITE_MINT = this.pottedPlant("potted_white_mint", WHITE_MINT_LEAF_LITTER)
val POTTED_WHITE_MINT = this.flowerPot("potted_white_mint", WHITE_MINT_LEAF_LITTER)
@JvmField
val LOBAILA = this.create("lobaila", LobailaFlowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().instabreak().sound(SoundType.GRASS).offsetType(BlockBehaviour.OffsetType.XZ).ignitedByLava().pushReaction(PushReaction.DESTROY)))
@@ -1104,145 +1085,163 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
//val BINDING_SOIL = this.create("binding_soil", BindingSoilBlock(BlockBehaviour.Properties.of()))
@JvmField
val POTTED_AGUAV_BERRY = this.create("potted_aguav_berry", BlocksInvoker.createFlowerPotBlock(AGUAV_BERRY))
val POTTED_AGUAV_BERRY = this.flowerPot("potted_aguav_berry", AGUAV_BERRY)
@JvmField
val POTTED_APICOT_BERRY = this.create("potted_apicot_berry", BlocksInvoker.createFlowerPotBlock(APICOT_BERRY))
val POTTED_APICOT_BERRY = this.flowerPot("potted_apicot_berry", APICOT_BERRY)
@JvmField
val POTTED_ASPEAR_BERRY = this.create("potted_aspear_berry", BlocksInvoker.createFlowerPotBlock(ASPEAR_BERRY))
val POTTED_ASPEAR_BERRY = this.flowerPot("potted_aspear_berry", ASPEAR_BERRY)
@JvmField
val POTTED_BABIRI_BERRY = this.create("potted_babiri_berry", BlocksInvoker.createFlowerPotBlock(BABIRI_BERRY))
val POTTED_BABIRI_BERRY = this.flowerPot("potted_babiri_berry", BABIRI_BERRY)
@JvmField
val POTTED_BELUE_BERRY = this.create("potted_belue_berry", BlocksInvoker.createFlowerPotBlock(BELUE_BERRY))
val POTTED_BELUE_BERRY = this.flowerPot("potted_belue_berry", BELUE_BERRY)
@JvmField
val POTTED_BLUK_BERRY = this.create("potted_bluk_berry", BlocksInvoker.createFlowerPotBlock(BLUK_BERRY))
val POTTED_BLUK_BERRY = this.flowerPot("potted_bluk_berry", BLUK_BERRY)
@JvmField
val POTTED_CHARTI_BERRY = this.create("potted_charti_berry", BlocksInvoker.createFlowerPotBlock(CHARTI_BERRY))
val POTTED_CHARTI_BERRY = this.flowerPot("potted_charti_berry", CHARTI_BERRY)
@JvmField
val POTTED_CHERI_BERRY = this.create("potted_cheri_berry", BlocksInvoker.createFlowerPotBlock(CHERI_BERRY))
val POTTED_CHERI_BERRY = this.flowerPot("potted_cheri_berry", CHERI_BERRY)
@JvmField
val POTTED_CHESTO_BERRY = this.create("potted_chesto_berry", BlocksInvoker.createFlowerPotBlock(CHESTO_BERRY))
val POTTED_CHESTO_BERRY = this.flowerPot("potted_chesto_berry", CHESTO_BERRY)
@JvmField
val POTTED_CHILAN_BERRY = this.create("potted_chilan_berry", BlocksInvoker.createFlowerPotBlock(CHILAN_BERRY))
val POTTED_CHILAN_BERRY = this.flowerPot("potted_chilan_berry", CHILAN_BERRY)
@JvmField
val POTTED_CHOPLE_BERRY = this.create("potted_chople_berry", BlocksInvoker.createFlowerPotBlock(CHOPLE_BERRY))
val POTTED_CHOPLE_BERRY = this.flowerPot("potted_chople_berry", CHOPLE_BERRY)
@JvmField
val POTTED_COBA_BERRY = this.create("potted_coba_berry", BlocksInvoker.createFlowerPotBlock(COBA_BERRY))
val POTTED_COBA_BERRY = this.flowerPot("potted_coba_berry", COBA_BERRY)
@JvmField
val POTTED_COLBUR_BERRY = this.create("potted_colbur_berry", BlocksInvoker.createFlowerPotBlock(COLBUR_BERRY))
val POTTED_COLBUR_BERRY = this.flowerPot("potted_colbur_berry", COLBUR_BERRY)
@JvmField
val POTTED_CORNN_BERRY = this.create("potted_cornn_berry", BlocksInvoker.createFlowerPotBlock(CORNN_BERRY))
val POTTED_CORNN_BERRY = this.flowerPot("potted_cornn_berry", CORNN_BERRY)
@JvmField
val POTTED_CUSTAP_BERRY = this.create("potted_custap_berry", BlocksInvoker.createFlowerPotBlock(CUSTAP_BERRY))
val POTTED_CUSTAP_BERRY = this.flowerPot("potted_custap_berry", CUSTAP_BERRY)
@JvmField
val POTTED_DURIN_BERRY = this.create("potted_durin_berry", BlocksInvoker.createFlowerPotBlock(DURIN_BERRY))
val POTTED_DURIN_BERRY = this.flowerPot("potted_durin_berry", DURIN_BERRY)
@JvmField
val POTTED_EGGANT_BERRY = this.create("potted_eggant_berry", BlocksInvoker.createFlowerPotBlock(EGGANT_BERRY))
val POTTED_EGGANT_BERRY = this.flowerPot("potted_eggant_berry", EGGANT_BERRY)
@JvmField
val POTTED_ENIGMA_BERRY = this.create("potted_enigma_berry", BlocksInvoker.createFlowerPotBlock(ENIGMA_BERRY))
val POTTED_ENIGMA_BERRY = this.flowerPot("potted_enigma_berry", ENIGMA_BERRY)
@JvmField
val POTTED_FIGY_BERRY = this.create("potted_figy_berry", BlocksInvoker.createFlowerPotBlock(FIGY_BERRY))
val POTTED_FIGY_BERRY = this.flowerPot("potted_figy_berry", FIGY_BERRY)
@JvmField
val POTTED_GANLON_BERRY = this.create("potted_ganlon_berry", BlocksInvoker.createFlowerPotBlock(GANLON_BERRY))
val POTTED_GANLON_BERRY = this.flowerPot("potted_ganlon_berry", GANLON_BERRY)
@JvmField
val POTTED_GREPA_BERRY = this.create("potted_grepa_berry", BlocksInvoker.createFlowerPotBlock(GREPA_BERRY))
val POTTED_GREPA_BERRY = this.flowerPot("potted_grepa_berry", GREPA_BERRY)
@JvmField
val POTTED_HABAN_BERRY = this.create("potted_haban_berry", BlocksInvoker.createFlowerPotBlock(HABAN_BERRY))
val POTTED_HABAN_BERRY = this.flowerPot("potted_haban_berry", HABAN_BERRY)
@JvmField
val POTTED_HONDEW_BERRY = this.create("potted_hondew_berry", BlocksInvoker.createFlowerPotBlock(HONDEW_BERRY))
val POTTED_HONDEW_BERRY = this.flowerPot("potted_hondew_berry", HONDEW_BERRY)
@JvmField
val POTTED_HOPO_BERRY = this.create("potted_hopo_berry", BlocksInvoker.createFlowerPotBlock(HOPO_BERRY))
val POTTED_HOPO_BERRY = this.flowerPot("potted_hopo_berry", HOPO_BERRY)
@JvmField
val POTTED_IAPAPA_BERRY = this.create("potted_iapapa_berry", BlocksInvoker.createFlowerPotBlock(IAPAPA_BERRY))
val POTTED_IAPAPA_BERRY = this.flowerPot("potted_iapapa_berry", IAPAPA_BERRY)
@JvmField
val POTTED_JABOCA_BERRY = this.create("potted_jaboca_berry", BlocksInvoker.createFlowerPotBlock(JABOCA_BERRY))
val POTTED_JABOCA_BERRY = this.flowerPot("potted_jaboca_berry", JABOCA_BERRY)
@JvmField
val POTTED_KASIB_BERRY = this.create("potted_kasib_berry", BlocksInvoker.createFlowerPotBlock(KASIB_BERRY))
val POTTED_KASIB_BERRY = this.flowerPot("potted_kasib_berry", KASIB_BERRY)
@JvmField
val POTTED_KEBIA_BERRY = this.create("potted_kebia_berry", BlocksInvoker.createFlowerPotBlock(KEBIA_BERRY))
val POTTED_KEBIA_BERRY = this.flowerPot("potted_kebia_berry", KEBIA_BERRY)
@JvmField
val POTTED_KEE_BERRY = this.create("potted_kee_berry", BlocksInvoker.createFlowerPotBlock(KEE_BERRY))
val POTTED_KEE_BERRY = this.flowerPot("potted_kee_berry", KEE_BERRY)
@JvmField
val POTTED_KELPSY_BERRY = this.create("potted_kelpsy_berry", BlocksInvoker.createFlowerPotBlock(KELPSY_BERRY))
val POTTED_KELPSY_BERRY = this.flowerPot("potted_kelpsy_berry", KELPSY_BERRY)
@JvmField
val POTTED_LANSAT_BERRY = this.create("potted_lansat_berry", BlocksInvoker.createFlowerPotBlock(LANSAT_BERRY))
val POTTED_LANSAT_BERRY = this.flowerPot("potted_lansat_berry", LANSAT_BERRY)
@JvmField
val POTTED_LEPPA_BERRY = this.create("potted_leppa_berry", BlocksInvoker.createFlowerPotBlock(LEPPA_BERRY))
val POTTED_LEPPA_BERRY = this.flowerPot("potted_leppa_berry", LEPPA_BERRY)
@JvmField
val POTTED_LIECHI_BERRY = this.create("potted_liechi_berry", BlocksInvoker.createFlowerPotBlock(LIECHI_BERRY))
val POTTED_LIECHI_BERRY = this.flowerPot("potted_liechi_berry", LIECHI_BERRY)
@JvmField
val POTTED_LUM_BERRY = this.create("potted_lum_berry", BlocksInvoker.createFlowerPotBlock(LUM_BERRY))
val POTTED_LUM_BERRY = this.flowerPot("potted_lum_berry", LUM_BERRY)
@JvmField
val POTTED_MAGO_BERRY = this.create("potted_mago_berry", BlocksInvoker.createFlowerPotBlock(MAGO_BERRY))
val POTTED_MAGO_BERRY = this.flowerPot("potted_mago_berry", MAGO_BERRY)
@JvmField
val POTTED_MAGOST_BERRY = this.create("potted_magost_berry", BlocksInvoker.createFlowerPotBlock(MAGOST_BERRY))
val POTTED_MAGOST_BERRY = this.flowerPot("potted_magost_berry", MAGOST_BERRY)
@JvmField
val POTTED_MARANGA_BERRY = this.create("potted_maranga_berry", BlocksInvoker.createFlowerPotBlock(MARANGA_BERRY))
val POTTED_MARANGA_BERRY = this.flowerPot("potted_maranga_berry", MARANGA_BERRY)
@JvmField
val POTTED_MICLE_BERRY = this.create("potted_micle_berry", BlocksInvoker.createFlowerPotBlock(MICLE_BERRY))
val POTTED_MICLE_BERRY = this.flowerPot("potted_micle_berry", MICLE_BERRY)
@JvmField
val POTTED_NANAB_BERRY = this.create("potted_nanab_berry", BlocksInvoker.createFlowerPotBlock(NANAB_BERRY))
val POTTED_NANAB_BERRY = this.flowerPot("potted_nanab_berry", NANAB_BERRY)
@JvmField
val POTTED_NOMEL_BERRY = this.create("potted_nomel_berry", BlocksInvoker.createFlowerPotBlock(NOMEL_BERRY))
val POTTED_NOMEL_BERRY = this.flowerPot("potted_nomel_berry", NOMEL_BERRY)
@JvmField
val POTTED_OCCA_BERRY = this.create("potted_occa_berry", BlocksInvoker.createFlowerPotBlock(OCCA_BERRY))
val POTTED_OCCA_BERRY = this.flowerPot("potted_occa_berry", OCCA_BERRY)
@JvmField
val POTTED_ORAN_BERRY = this.create("potted_oran_berry", BlocksInvoker.createFlowerPotBlock(ORAN_BERRY))
val POTTED_ORAN_BERRY = this.flowerPot("potted_oran_berry", ORAN_BERRY)
@JvmField
val POTTED_PAMTRE_BERRY = this.create("potted_pamtre_berry", BlocksInvoker.createFlowerPotBlock(PAMTRE_BERRY))
val POTTED_PAMTRE_BERRY = this.flowerPot("potted_pamtre_berry", PAMTRE_BERRY)
@JvmField
val POTTED_PASSHO_BERRY = this.create("potted_passho_berry", BlocksInvoker.createFlowerPotBlock(PASSHO_BERRY))
val POTTED_PASSHO_BERRY = this.flowerPot("potted_passho_berry", PASSHO_BERRY)
@JvmField
val POTTED_PAYAPA_BERRY = this.create("potted_payapa_berry", BlocksInvoker.createFlowerPotBlock(PAYAPA_BERRY))
val POTTED_PAYAPA_BERRY = this.flowerPot("potted_payapa_berry", PAYAPA_BERRY)
@JvmField
val POTTED_PECHA_BERRY = this.create("potted_pecha_berry", BlocksInvoker.createFlowerPotBlock(PECHA_BERRY))
val POTTED_PECHA_BERRY = this.flowerPot("potted_pecha_berry", PECHA_BERRY)
@JvmField
val POTTED_PERSIM_BERRY = this.create("potted_persim_berry", BlocksInvoker.createFlowerPotBlock(PERSIM_BERRY))
val POTTED_PERSIM_BERRY = this.flowerPot("potted_persim_berry", PERSIM_BERRY)
@JvmField
val POTTED_PETAYA_BERRY = this.create("potted_petaya_berry", BlocksInvoker.createFlowerPotBlock(PETAYA_BERRY))
val POTTED_PETAYA_BERRY = this.flowerPot("potted_petaya_berry", PETAYA_BERRY)
@JvmField
val POTTED_PINAP_BERRY = this.create("potted_pinap_berry", BlocksInvoker.createFlowerPotBlock(PINAP_BERRY))
val POTTED_PINAP_BERRY = this.flowerPot("potted_pinap_berry", PINAP_BERRY)
@JvmField
val POTTED_POMEG_BERRY = this.create("potted_pomeg_berry", BlocksInvoker.createFlowerPotBlock(POMEG_BERRY))
val POTTED_POMEG_BERRY = this.flowerPot("potted_pomeg_berry", POMEG_BERRY)
@JvmField
val POTTED_QUALOT_BERRY = this.create("potted_qualot_berry", BlocksInvoker.createFlowerPotBlock(QUALOT_BERRY))
val POTTED_QUALOT_BERRY = this.flowerPot("potted_qualot_berry", QUALOT_BERRY)
@JvmField
val POTTED_RABUTA_BERRY = this.create("potted_rabuta_berry", BlocksInvoker.createFlowerPotBlock(RABUTA_BERRY))
val POTTED_RABUTA_BERRY = this.flowerPot("potted_rabuta_berry", RABUTA_BERRY)
@JvmField
val POTTED_RAWST_BERRY = this.create("potted_rawst_berry", BlocksInvoker.createFlowerPotBlock(RAWST_BERRY))
val POTTED_RAWST_BERRY = this.flowerPot("potted_rawst_berry", RAWST_BERRY)
@JvmField
val POTTED_RAZZ_BERRY = this.create("potted_razz_berry", BlocksInvoker.createFlowerPotBlock(RAZZ_BERRY))
val POTTED_RAZZ_BERRY = this.flowerPot("potted_razz_berry", RAZZ_BERRY)
@JvmField
val POTTED_RINDO_BERRY = this.create("potted_rindo_berry", BlocksInvoker.createFlowerPotBlock(RINDO_BERRY))
val POTTED_RINDO_BERRY = this.flowerPot("potted_rindo_berry", RINDO_BERRY)
@JvmField
val POTTED_ROSELI_BERRY = this.create("potted_roseli_berry", BlocksInvoker.createFlowerPotBlock(ROSELI_BERRY))
val POTTED_ROSELI_BERRY = this.flowerPot("potted_roseli_berry", ROSELI_BERRY)
@JvmField
val POTTED_ROWAP_BERRY = this.create("potted_rowap_berry", BlocksInvoker.createFlowerPotBlock(ROWAP_BERRY))
val POTTED_ROWAP_BERRY = this.flowerPot("potted_rowap_berry", ROWAP_BERRY)
@JvmField
val POTTED_SALAC_BERRY = this.create("potted_salac_berry", BlocksInvoker.createFlowerPotBlock(SALAC_BERRY))
val POTTED_SALAC_BERRY = this.flowerPot("potted_salac_berry", SALAC_BERRY)
@JvmField
val POTTED_SHUCA_BERRY = this.create("potted_shuca_berry", BlocksInvoker.createFlowerPotBlock(SHUCA_BERRY))
val POTTED_SHUCA_BERRY = this.flowerPot("potted_shuca_berry", SHUCA_BERRY)
@JvmField
val POTTED_SITRUS_BERRY = this.create("potted_sitrus_berry", BlocksInvoker.createFlowerPotBlock(SITRUS_BERRY))
val POTTED_SITRUS_BERRY = this.flowerPot("potted_sitrus_berry", SITRUS_BERRY)
@JvmField
val POTTED_SPELON_BERRY = this.create("potted_spelon_berry", BlocksInvoker.createFlowerPotBlock(SPELON_BERRY))
val POTTED_SPELON_BERRY = this.flowerPot("potted_spelon_berry", SPELON_BERRY)
@JvmField
val POTTED_STARF_BERRY = this.create("potted_starf_berry", BlocksInvoker.createFlowerPotBlock(STARF_BERRY))
val POTTED_STARF_BERRY = this.flowerPot("potted_starf_berry", STARF_BERRY)
@JvmField
val POTTED_TAMATO_BERRY = this.create("potted_tamato_berry", BlocksInvoker.createFlowerPotBlock(TAMATO_BERRY))
val POTTED_TAMATO_BERRY = this.flowerPot("potted_tamato_berry", TAMATO_BERRY)
@JvmField
val POTTED_TANGA_BERRY = this.create("potted_tanga_berry", BlocksInvoker.createFlowerPotBlock(TANGA_BERRY))
val POTTED_TANGA_BERRY = this.flowerPot("potted_tanga_berry", TANGA_BERRY)
@JvmField
val POTTED_TOUGA_BERRY = this.create("potted_touga_berry", BlocksInvoker.createFlowerPotBlock(TOUGA_BERRY))
val POTTED_TOUGA_BERRY = this.flowerPot("potted_touga_berry", TOUGA_BERRY)
@JvmField
val POTTED_WACAN_BERRY = this.create("potted_wacan_berry", BlocksInvoker.createFlowerPotBlock(WACAN_BERRY))
val POTTED_WACAN_BERRY = this.flowerPot("potted_wacan_berry", WACAN_BERRY)
@JvmField
val POTTED_WATMEL_BERRY = this.create("potted_watmel_berry", BlocksInvoker.createFlowerPotBlock(WATMEL_BERRY))
val POTTED_WATMEL_BERRY = this.flowerPot("potted_watmel_berry", WATMEL_BERRY)
@JvmField
val POTTED_WEPEAR_BERRY = this.create("potted_wepear_berry", BlocksInvoker.createFlowerPotBlock(WEPEAR_BERRY))
val POTTED_WEPEAR_BERRY = this.flowerPot("potted_wepear_berry", WEPEAR_BERRY)
@JvmField
val POTTED_WIKI_BERRY = this.create("potted_wiki_berry", BlocksInvoker.createFlowerPotBlock(WIKI_BERRY))
val POTTED_WIKI_BERRY = this.flowerPot("potted_wiki_berry", WIKI_BERRY)
@JvmField
val POTTED_YACHE_BERRY = this.create("potted_yache_berry", BlocksInvoker.createFlowerPotBlock(YACHE_BERRY))
val POTTED_YACHE_BERRY = this.flowerPot("potted_yache_berry", YACHE_BERRY)
@JvmField
val POTTED_PEP_UP_FLOWER = this.flowerPot("potted_pep_up_flower", PEP_UP_FLOWER)
@JvmField
val POTTED_RED_APRICORN_SAPLING = this.flowerPot("potted_red_apricorn_sapling", RED_APRICORN_SAPLING)
@JvmField
val POTTED_YELLOW_APRICORN_SAPLING = this.flowerPot("potted_yellow_apricorn_sapling", YELLOW_APRICORN_SAPLING)
@JvmField
val POTTED_GREEN_APRICORN_SAPLING = this.flowerPot("potted_green_apricorn_sapling", GREEN_APRICORN_SAPLING)
@JvmField
val POTTED_BLUE_APRICORN_SAPLING = this.flowerPot("potted_blue_apricorn_sapling", BLUE_APRICORN_SAPLING)
@JvmField
val POTTED_PINK_APRICORN_SAPLING = this.flowerPot("potted_pink_apricorn_sapling", PINK_APRICORN_SAPLING)
@JvmField
val POTTED_BLACK_APRICORN_SAPLING = this.flowerPot("potted_black_apricorn_sapling", BLACK_APRICORN_SAPLING)
@JvmField
val POTTED_WHITE_APRICORN_SAPLING = this.flowerPot("potted_white_apricorn_sapling", WHITE_APRICORN_SAPLING)
@JvmField
val POTTED_SACCHARINE_SAPLING = this.flowerPot("potted_saccharine_sapling", SACCHARINE_SAPLING)
init {
/**
@@ -1346,7 +1345,16 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
fun typeGemClusters() = typeGemClusters.toMap()
private fun pottedPlant(name: String, flower: Block) = this.create(name, BlocksInvoker.createFlowerPotBlock(flower))
private fun flowerPot(name: String, flower: Block) = this.create(
name,
FlowerPotBlock(
flower,
BlockBehaviour.Properties.of()
.instabreak()
.noOcclusion()
.pushReaction(PushReaction.DESTROY)
)
)
private fun mintLitter(name: String, color: MapColor) = this.create(
name,
@@ -20,6 +20,7 @@ import com.cobblemon.mod.common.api.riding.behaviour.types.air.HelicopterSetting
import com.cobblemon.mod.common.api.riding.behaviour.types.air.HoverSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.JetSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.RocketSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.BoardSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.HorseSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleSettings
@@ -56,6 +57,7 @@ object CobblemonRideSettings : DataRegistry {
var hover = HoverSettings()
var jet = JetSettings()
var rocket = RocketSettings()
var board = BoardSettings()
var horse = HorseSettings()
var minekart = MinekartSettings()
@@ -75,6 +77,7 @@ object CobblemonRideSettings : DataRegistry {
hover = hover,
jet = jet,
rocket = rocket,
board = board,
horse = horse,
minekart = minekart,
vehicle = vehicle,
@@ -93,6 +96,7 @@ object CobblemonRideSettings : DataRegistry {
hover = loadStyle(manager, "hover", HoverSettings::class.java)
jet = loadStyle(manager, "jet", JetSettings::class.java)
rocket = loadStyle(manager, "rocket", RocketSettings::class.java)
board = loadStyle(manager, "board", BoardSettings::class.java)
horse = loadStyle(manager, "horse", HorseSettings::class.java)
minekart = loadStyle(manager, "minekart", MinekartSettings::class.java)
vehicle = loadStyle(manager, "vehicle", VehicleSettings::class.java)
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
@@ -17,6 +18,7 @@ import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
@@ -34,6 +36,8 @@ import net.minecraft.world.entity.ai.sensing.SensorType
class HateEntityTaskConfig : SingleTaskConfig {
val entityCondition: Expression = "true".asExpression()
val range: ExpressionOrEntityVariable = Either.left("24".asExpression())
val chance: Float = Cobblemon.config.predationChance
private val coercedChance = chance.coerceIn(0f, 1f)
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
@@ -43,24 +47,44 @@ class HateEntityTaskConfig : SingleTaskConfig {
val range = range.resolveFloat(behaviourConfigurationContext.runtime)
behaviourConfigurationContext.addMemories(
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
MemoryModuleType.ANGRY_AT
MemoryModuleType.ANGRY_AT,
MemoryModuleType.ATTACK_TARGET
)
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
return BehaviorBuilder.create { instance ->
instance.group(
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
instance.registered(MemoryModuleType.ANGRY_AT)
).apply(instance) { entities, angryAt ->
instance.registered(MemoryModuleType.ANGRY_AT),
instance.registered(MemoryModuleType.ATTACK_TARGET),
).apply(instance) { entities, angryAt, attackTarget ->
Trigger { world, entity, _ ->
val target = instance.get(entities).findClosest {
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
// bail if gamerule is disabled
if (!world.gameRules.getBoolean(CobblemonGameRules.DO_POKEMON_PREDATION)) return@Trigger false
val target = instance.get(entities).findClosest { hated ->
mainThreadRuntime.withQueryValue("entity", hated.asMostSpecificMoLangValue())
return@findClosest mainThreadRuntime.resolveBoolean(entityCondition)
}.orElse(null)
var shouldTrigger = false
if (target != null && target.distanceTo(entity) <= range) {
angryAt.set(target.uuid)
shouldTrigger = when {
// set always attacking if activity chance is equal to 1.0
coercedChance == 1f -> {
angryAt.set(target.uuid)
attackTarget.set(target)
true
}
// roll the dice in other way
coercedChance != 1f && world.random.nextFloat() < coercedChance -> {
angryAt.set(target.uuid)
attackTarget.set(target)
true
}
// fallback to peaceful behavior in unattended cases
else -> false
}
}
return@Trigger true
return@Trigger shouldTrigger
}
}
}
@@ -239,6 +239,10 @@ open class PokemonBattle(
}
fun writeShowdownAction(vararg messages: String) {
if (messages.any { it.contains("\n") || it.contains("\r") }) {
LOGGER.warn("Refusing to forward Showdown action with an embedded line break for battle {}: {}", battleId, messages.joinToString(" | "))
return
}
log(messages.joinToString("\n"))
ShowdownService.service.send(battleId, messages.toList().toTypedArray())
}
@@ -29,7 +29,8 @@ open class OrientationController(val entity: LivingEntity) {
val UP: Vector3f = Vector3f(0.0f, 1.0f, 0.0f)
val LEFT: Vector3f = Vector3f(-1.0f, 0.0f, 0.0f)
private const val TICK_DT = 1f / 20f // Minecraft server tick rate
private const val RENDER_SMOOTH_HALFLIFE = 0.1f // seconds to close ~half the gap
// Seconds for the render orientation to close half the gap to the real one. Raise for smoother but laggier visuals
private const val RENDER_SMOOTH_HALFLIFE = 0.15f
}
open var active: Boolean = false
@@ -101,7 +102,7 @@ open class OrientationController(val entity: LivingEntity) {
// Use a "quat spring" to smoothly move the render orientation towards the goal orientation.
// It takes into account the orientations angular velocities and should be much more resilient
// to sharp changes in goal orientation or late/missed packets.
simpleSpringDamperQuat(renderSpring, targetQuat, 0.15f, TICK_DT)
simpleSpringDamperQuat(renderSpring, targetQuat, RENDER_SMOOTH_HALFLIFE, TICK_DT)
val newRenderOrientation = Matrix3f()
renderSpring.quat.get(newRenderOrientation)
@@ -88,7 +88,7 @@ fun getToolTipHeaderIcon(tradeEvolution: TradeEvolution): CobblemonDexEvolutionR
lang("ui.pokedex.evolution.trade.tooltip.with_any_species")
} else {
PokemonSpecies.getByIdentifier(species.asIdentifierDefaultingNamespace())
?.let { lang("ui.pokedex.evolution.trade.tooltip.with_species", it.translatedName.green()) }
?.let { lang("ui.pokedex.evolution.trade.tooltip.with_species", it.translatedName.plainCopy().green()) }
?: lang("ui.pokedex.evolution.trade.tooltip.with_any_species")
}
return CobblemonDexEvolutionRequirementDisplay(CobblemonItems.LINK_CABLE, tooltip)
@@ -282,7 +282,7 @@ fun buildLevelRequirement(levelRequirement: LevelRequirement): DexEvolutionRequi
fun buildMoonPhaseRequirement(moonPhaseRequirement: MoonPhaseRequirement): DexEvolutionRequirementDisplay {
val icon = Items.CLOCK
val moonPhaseComponent = moonPhaseRequirement.moonPhase.displayName().green()
val moonPhaseComponent = moonPhaseRequirement.moonPhase.displayName().plainCopy().green()
val tooltip = lang("ui.pokedex.requirement.moon_phase.tooltip", moonPhaseComponent)
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
@@ -290,7 +290,7 @@ fun buildMoonPhaseRequirement(moonPhaseRequirement: MoonPhaseRequirement): DexEv
fun buildMoveSetRequirement(moveSetRequirement: MoveSetRequirement): DexEvolutionRequirementDisplay {
val icon = CobblemonItems.TECHNICAL_MACHINE
val tooltip = lang("ui.pokedex.requirement.has_move.tooltip", moveSetRequirement.move.displayName.green())
val tooltip = lang("ui.pokedex.requirement.has_move.tooltip", moveSetRequirement.move.displayName.plainCopy().green())
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
}
@@ -319,7 +319,7 @@ fun buildMoveTypeRequirement(moveTypeRequirement: MoveTypeRequirement): DexEvolu
else -> CobblemonItems.NORMAL_GEM
}
val tooltip = lang("ui.pokedex.requirement.has_move_type.tooltip", moveTypeRequirement.type.displayName.green())
val tooltip = lang("ui.pokedex.requirement.has_move_type.tooltip", moveTypeRequirement.type.displayName.plainCopy().green())
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
}
@@ -437,7 +437,7 @@ fun buildStructureRequirement(structureRequirement: StructureRequirement, negate
fun buildTimeRangeRequirement(timeRangeRequirement: TimeRangeRequirement): DexEvolutionRequirementDisplay? {
val icon = Items.CLOCK
val timeRangeComponent = timeRangeRequirement.range.displayName() ?: return null
val timeRangeComponent = timeRangeRequirement.range.displayName()?.plainCopy() ?: return null
val tooltip = lang("ui.pokedex.requirement.time_range.tooltip", timeRangeComponent.green())
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
@@ -445,7 +445,7 @@ fun buildTimeRangeRequirement(timeRangeRequirement: TimeRangeRequirement): DexEv
fun buildUseMoveRequirement(useMoveRequirement: UseMoveRequirement): DexEvolutionRequirementDisplay {
val icon = CobblemonItems.CHOICE_BAND
val tooltip = lang("ui.pokedex.requirement.use_move.tooltip", useMoveRequirement.move.displayName.green())
val tooltip = lang("ui.pokedex.requirement.use_move.tooltip", useMoveRequirement.move.displayName.plainCopy().green())
return CobblemonDexEvolutionRequirementDisplay(icon, tooltip)
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.air.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.ClimbBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.HorseBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartBehaviour
@@ -35,7 +36,9 @@ object RidingBehaviours {
register(MinekartBehaviour.KEY, MinekartBehaviour())
register(HoverBehaviour.KEY, HoverBehaviour())
register(RocketBehaviour.KEY, RocketBehaviour())
register(BoardBehaviour.KEY, BoardBehaviour())
register(SubmarineBehaviour.KEY, SubmarineBehaviour())
register(ClimbBehaviour.KEY, ClimbBehaviour())
register(CompositeBehaviour.KEY, CompositeBehaviour())
}
@@ -0,0 +1,924 @@
/*
* 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.air
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.orientation.OrientationController
import com.cobblemon.mod.common.api.riding.RidingStyle
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.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.Side
import com.cobblemon.mod.common.api.riding.behaviour.ridingState
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.api.riding.sound.RideSoundSettingsList
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.api.riding.util.DistanceFieldLayer
import com.cobblemon.mod.common.api.riding.util.DistanceFieldTuning
import com.cobblemon.mod.common.api.riding.util.PrimitiveShape
import com.cobblemon.mod.common.api.riding.util.collectPrimitivesFromBlocks
import com.cobblemon.mod.common.api.riding.util.estimateGradient
import com.cobblemon.mod.common.api.riding.util.sampleField
import com.cobblemon.mod.common.api.riding.util.visualizeDistanceField
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.blockPositionsAsListRounded
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readNullableExpression
import com.cobblemon.mod.common.util.readRidingStats
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.resolveDouble
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.writeNullableExpression
import com.cobblemon.mod.common.util.writeRidingStats
import net.minecraft.client.Minecraft
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sign
import kotlin.math.sqrt
import net.minecraft.core.Direction
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.network.FriendlyByteBuf
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.ai.attributes.Attributes
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
class BoardBehaviour : RidingBehaviour<BoardSettings, BoardState> {
companion object {
val KEY = cobblemonResource("air/board")
}
override val key = KEY
val globalBoard: BoardSettings
get() = CobblemonRideSettings.board
override fun getRidingStyle(settings: BoardSettings, state: BoardState): RidingStyle {
return RidingStyle.LAND
}
val poseProvider = PoseProvider<BoardSettings, BoardState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, vehicle ->
return@PoseOption state.walking.get()
})
override fun isActive(
settings: BoardSettings,
state: BoardState,
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: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): PoseType {
return this.poseProvider.select(settings, state, vehicle)
}
override fun speed(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVelocity.get().length().toFloat()
}
override fun tick(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (vehicle.level().isClientSide) {
handleSprinting(state, driver)
inAirCheck(state, vehicle)
tickStamina(settings, state, vehicle)
state.walking.set(state.rideVelocity.get().horizontalDistance() > 0.1 || driver.zza != 0.0f)
//surfDistCheck(state, vehicle)
}
//TODO: should be a config somewhere
val debugVisualizeField = true;
if (false && debugVisualizeField && !vehicle.level().isClientSide && vehicle.tickCount % 5 == 0) {
visualizeDistanceField(
referenceEntity = vehicle,
center = vehicle.position().add(0.0, (vehicle.bbHeight * 0.5f).toDouble(), 0.0),
layers = listOf(
DistanceFieldLayer(isoValue = 2.5f, color = Vector3f(1f, 0.2f, 0.2f))
),
shape = PrimitiveShape.ELLIPSOID,
horizontalRadius = 4.0,
verticalRange = 4.0,
sampleSpacing = 0.3,
marchStep = 0.15,
tuning = DistanceFieldTuning(smoothingRange = 0.25f)
)
}
}
/**
* Check how far the vehicle is from the "surface"
*/
fun surfDistCheck(
state: BoardState,
vehicle: PokemonEntity,
) {
val center = vehicle.position()
val horizontalRadius = 4.0;
val verticalRange = 4.0;
val level = vehicle.level()
//if (level !is ServerLevel) return
// Take a cubic area around the vehicle and gather SDF primitives from it.
val searchBox = AABB(
center.x - horizontalRadius, center.y - verticalRange, center.z - horizontalRadius,
center.x + horizontalRadius, center.y + verticalRange, center.z + horizontalRadius
)
val primitives = collectPrimitivesFromBlocks(level,
searchBox,
PrimitiveShape.ELLIPSOID,
includeFluids = true
)
val sp = center.toVector3f() // Sample Point
val tuning = DistanceFieldTuning(smoothingRange = 0.25f)
val sd = sampleField(primitives, sp.x, sp.y, sp.z, tuning)
state.surfDist.set(sd)
}
fun inAirCheck(
state: BoardState,
vehicle: PokemonEntity,
) {
// Check both vertical movement and if there are blocks below.
val posBelow = vehicle.blockPosition().below()
val blockStateBelow = vehicle.level().getBlockState(posBelow)
val isAirOrLiquid = blockStateBelow.isAir || !blockStateBelow.fluidState.isEmpty
val canSupportEntity = blockStateBelow.isFaceSturdy(vehicle.level(), posBelow, Direction.UP)
val standingOnSolid = canSupportEntity && !isAirOrLiquid
// inAir if not on the ground
val inAir = !(vehicle.deltaMovement.y == 0.0 || standingOnSolid)
state.inAir.set(true)
}
fun handleSprinting(
state: BoardState,
driver: Player
) {
val sprintTimerTickLength = 7 // Emulate vanillas tick timer length
var hasDoubleTapped = false
// If you are not sprinting and you just pressed down and theres no
if (!state.forwardHeldLastTick.get() && Minecraft.getInstance().options.keyUp.isDown() && !state.sprinting.get() && state.sprintTickTimer.get() == 0) {
state.sprintTickTimer.set(sprintTimerTickLength)
} else if (!state.forwardHeldLastTick.get() && Minecraft.getInstance().options.keyUp.isDown() && state.sprintTickTimer.get() != 0) { // If has double tapped
hasDoubleTapped = true
}else if(!state.sprinting.get() && state.sprintTickTimer.get() > 0) {
state.sprintTickTimer.set(state.sprintTickTimer.get() - 1)
} else {
state.sprintTickTimer.set(0)
}
val tryingToSprint = (Minecraft.getInstance().options.keySprint.isDown() && Minecraft.getInstance().options.keyUp.isDown()) || hasDoubleTapped
if (state.stamina.get() <= 0.0f || !Minecraft.getInstance().options.keyUp.isDown()) {
// If stamina runs out or the player is not holding forward then stop sprinting
state.sprinting.set(false)
if (state.stamina.get() <= 0.0f) {
state.sprintToggleable.set(false)
}
} else if (!state.sprinting.get() && !state.sprintToggleable.get() && state.stamina.get() > 0.33f) {
// If you are not sprinting and sprint is not toggleable and you're not trying to sprint and stamina is above 0.3 then enable the toggle
state.sprintToggleable.set(true)
} else if (tryingToSprint && state.sprintToggleable.get()) {
// If you are trying to sprint and the toggle allows it then start sprinting and disable toggle
state.sprinting.set(true)
}
// Take not of whether forward was held last tick
state.forwardHeldLastTick.set(Minecraft.getInstance().options.keyUp.isDown())
}
fun tickStamina(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
) {
val stam = state.stamina.get()
if (vehicle.runtime.resolveBoolean(settings.infiniteStamina ?: globalBoard.infiniteStamina!!)) {
return
}
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalBoard.staminaExpr!!)).toFloat() / 20.0f
val newStam = if (state.sprinting.get()) {
max(0.0f,stam - stamDrainRate)
} else {
min(1.0f,stam + stamDrainRate * 4)
}
state.stamina.set(newStam.coerceIn(0F, 1F))
}
override fun updatePassengerRotation(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: LivingEntity
) { return }
override fun clampPassengerRotation(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: LivingEntity
) { }
override fun rotation(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
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: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBoard.speedExpr!!)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalBoard.handlingExpr!!)
val walkHandlingBoost = 5
val maxYawDiff = vehicle.runtime.resolveFloat(settings.lookYawLimit ?: globalBoard.lookYawLimit!!)
// Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot).coerceIn(-maxYawDiff,maxYawDiff)
val rotDiffNorm = rotDiff / maxYawDiff//(rotDiff / maxYawDiff).coerceIn(-0.2f, 0.2f)
// 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 minRotMod = 0.4f // Min speed that the rotation modulation converges towards
val rotDiffMod = ((sqrt(abs(rotDiffNorm)) * (1.0f - minRotMod)) + minRotMod) * rotDiffNorm.sign
// Turn rate should be quick when walking and slower when sprinting.
// Smoothly move between these based on speed
val walkSpeed = getWalkSpeed(vehicle)
val w = max(walkSpeed, vehicle.deltaMovement.horizontalDistance())
val invRelSpeed = (RidingBehaviour.scaleToRange(w, walkSpeed, topSpeed ) - 1.0f) * -1.0f
val turnRate = ((handling.toFloat() / 20.0f) * max(walkHandlingBoost * sqrt(abs(invRelSpeed)), 1.0)).toFloat()
// Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod
val rotAmount = turnSpeed.coerceIn(-abs(rotDiff), abs(rotDiff))
return rotAmount
}
private fun spawnGradientDebugParticles(vehicle: PokemonEntity, normal: Vec3) {
val level = vehicle.level()
val headPos = vehicle.position().add(0.0, vehicle.bbHeight.toDouble(), 0.0)
val steps = 20
val length = 2.0
for (i in 0..steps) {
val t = i.toDouble() / steps
val point = headPos.add(normal.scale(length * t))
level.addParticle(ParticleTypes.END_ROD, point.x, point.y, point.z, 0.0, 0.0, 0.0)
}
}
override fun velocity(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
state.rideVelocity.set(calculateRideSpaceVel(settings, state, vehicle, driver))
return state.rideVelocity.get()
}
private fun calculateRideSpaceVel(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val canSprint = vehicle.runtime.resolveBoolean(settings.canSprint ?: globalBoard.canSprint!!)
val canJump = vehicle.runtime.resolveBoolean(settings.canJump ?: globalBoard.canJump!!)
val jumpForce = vehicle.runtime.resolveDouble(settings.jumpExpr ?: globalBoard.jumpExpr!!) * 0.75
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBoard.speedExpr!!)
val walkSpeed = getWalkSpeed(vehicle)
val topSpeed = if(canSprint && state.sprinting.get()) rideTopSpeed else walkSpeed
val accelTime = if(state.sprinting.get()) (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalBoard.accelerationExpr!!) * 20.0) else 0.5 * 20.0
val accel = topSpeed / accelTime
var activeInput = false
/******************************************************
* Gather the previous velocity and check for horizontal
* collisions
*****************************************************/
var newVelocity = state.rideVelocity.get() //.normalize().scale(vehicle.deltaMovement.horizontalDistance())
/******************************************************
* Gather the previous velocity and check for horizontal
* collisions
*****************************************************/
if (vehicle.horizontalCollision) {
var horizontalVec = Vec3(newVelocity.x, 0.0, newVelocity.z)
horizontalVec = horizontalVec.normalize().scale(min(horizontalVec.length(), 0.3))
newVelocity = Vec3(horizontalVec.x, newVelocity.y, horizontalVec.z)
}
/******************************************************
* Speed up and slow down based on input
*****************************************************/
if (driver.zza != 0.0f) {
// If on a tight turn then do not speed up past half of top speed in order to turn quicker
// Also determine how fast to be slowing down based on how far turned you are
val lookYawLimit = vehicle.runtime.resolveFloat(settings.lookYawLimit ?: globalBoard.lookYawLimit!!)
val percOfMaxTurnSpeed = abs(Mth.wrapDegrees(driver.yRot - vehicle.yRot) / lookYawLimit) * 100.0f
val turnPercThresh = 0.0f
val s = min(((percOfMaxTurnSpeed - turnPercThresh) / (100.0f - turnPercThresh)).pow(1),1.0f)
val effectiveTopSpeed = if (percOfMaxTurnSpeed > turnPercThresh) topSpeed / max(2.0f*s,1.0f) else topSpeed
val turningSlowDown = s * 0.1
//make sure it can't exceed top speed
val forwardInput = when {
driver.zza > 0 && newVelocity.z > effectiveTopSpeed -> 0.0
driver.zza < 0 && newVelocity.z < (-effectiveTopSpeed / 3.0) -> 0.0
else -> driver.zza.sign
}
// Add extra friction if trying to slow down to turn faster
if (newVelocity.z > effectiveTopSpeed) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(turningSlowDown * newVelocity.z.sign, newVelocity.z))
}
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
}
/******************************************************
* Gravity logic
*****************************************************/
// if(state.surfDist.get() > 1.6f) {
// val gravity = (9.8 / ( 20.0)) * 0.2 * 0.6
// val terminalVel = 2.0
// newVelocity = Vec3(newVelocity.x, max(newVelocity.y - gravity, -terminalVel), newVelocity.z)
// } else if(state.surfDist.get() > 1.4f && state.surfDist.get() <= 1.6f) {
// newVelocity = Vec3(newVelocity.x, 0.0, newVelocity.z)
// } else if(state.surfDist.get() <= 1.4f) {
// val gravity = -(9.8 / ( 20.0)) * 0.2 * 0.6
// val terminalVel = -2.0
// newVelocity = Vec3(newVelocity.x, min(newVelocity.y - gravity, -terminalVel), newVelocity.z)
// }
/******************************************************
* Hover logic - non-predictive: correct against current position
*****************************************************/
val correctionGain = 0.5
val maxCorrectionSpeed = 0.3
val center = vehicle.position()
val horizontalRadius = 4.0;
val verticalRange = 4.0;
val level = vehicle.level()
// Take a cubic area around the vehicle and gather SDF primitives from it.
val searchBox = AABB(
center.x - horizontalRadius, center.y - verticalRange, center.z - horizontalRadius,
center.x + horizontalRadius, center.y + vehicle.bbHeight, center.z + horizontalRadius
)
val primitives = collectPrimitivesFromBlocks(level,
searchBox,
PrimitiveShape.ELLIPSOID,
includeFluids = true
)
val tuning = DistanceFieldTuning(smoothingRange = 0.25f)
val currentPos = vehicle.position()
val currentDist = sampleField(primitives, currentPos.x.toFloat(), currentPos.y.toFloat(), currentPos.z.toFloat(), tuning)
val normal = estimateGradient(primitives, currentPos, tuning)
state.surfaceNormal.set(normal)
//spawnGradientDebugParticles(vehicle, normal) // LETS SEE IT!
// Only correct when under the hover surface.
// Otherwise allow gravity to do its thing
// if (currentDist < targetHoverDist) {
// val error = currentDist - targetHoverDist
// val normalSpeed = newVelocity.dot(normal)
// val tangentialVelocity = newVelocity.subtract(normal.scale(normalSpeed))
//
// val correctionSpeed = (-error * correctionGain).coerceIn(-maxCorrectionSpeed, maxCorrectionSpeed)
// newVelocity = tangentialVelocity.add(normal.scale(correctionSpeed))
// } else {
// val hoverCoolnessLowGravFactor = 0.5
// val gravity = (9.8 / ( 20.0)) * 0.2 * 0.6 * hoverCoolnessLowGravFactor
// val terminalVel = 2.0 * hoverCoolnessLowGravFactor
// newVelocity = Vec3(newVelocity.x, max(newVelocity.y - gravity, -terminalVel), newVelocity.z)
// }
/******************************************************
* Hover logic
*****************************************************/
val hoverActivationDist = 3.0f
val targetHoverDist = 1.0f
val hoverCoolnessLowGravFactor = 0.70
val gravity = (9.8 / 20.0) * 0.2 * 0.6 * hoverCoolnessLowGravFactor
val terminalVel = 2.0 * hoverCoolnessLowGravFactor
// val repelStrength = 0.05 // tested and was alright
// val hoverDamping = 0.15
val repelStrength = 0.1
val hoverDamping = 0.2
val surfDist = currentDist
if (surfDist > hoverActivationDist) {
// Free fall - no surface influence yet, same as before.
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - gravity, -terminalVel), newVelocity.z)
} else {
// Getting close - push back toward targetHoverDist, harder the nearer we are.
val closeness = ((hoverActivationDist - surfDist) / (hoverActivationDist - targetHoverDist)).coerceIn(0f, 1.5f)
val repelForce = closeness * repelStrength
val dampingForce = -newVelocity.y * hoverDamping // resists overshoot/bounce
newVelocity = Vec3(newVelocity.x, newVelocity.y + repelForce + dampingForce - gravity * 0.3, newVelocity.z)
}
/******************************************************
* Ground Friction
// *****************************************************/
// if( (newVelocity.horizontalDistance() > 0 && vehicle.onGround() && !activeInput) || newVelocity.horizontalDistance() > topSpeed) {
// newVelocity = newVelocity.subtract(0.0, 0.0, min(0.03 * newVelocity.z.sign, newVelocity.z))
// }
/******************************************************
* Jump Logic
*****************************************************/
if (state.jumpTicks.get() > 0 || (state.jumpTicks.get() >= 0 && driver.jumping && vehicle.onGround() && canJump && driver.deltaMovement.y <= 0.1)) {
// Spread out jumpforce so that variable height jumps are possible
val jumpInputTicks = 6
if (driver.jumping && (state.jumpTicks.get() >= 0 && state.jumpTicks.get() < jumpInputTicks)) {
val appliedJumpForce = ((jumpForce*1.5) / jumpInputTicks) //* (1 - state.jumpTicks.get() / jumpInputTicks)
newVelocity = Vec3(newVelocity.x, newVelocity.y + appliedJumpForce, newVelocity.z)
state.jumpTicks.set(state.jumpTicks.get() + 1)
} else {
// Set delay before next jump is possible after hitting ground
val tickJumpDelay = 3
state.jumpTicks.set(-tickJumpDelay)
}
} else if (vehicle.onGround() && state.jumpTicks.get() < 0) {
// Tick off the delay once reaching the ground
state.jumpTicks.set(state.jumpTicks.get() + 1)
}
// Zero out lateral velocity possibly picked up from a controller transition
newVelocity = Vec3(0.0, newVelocity.y, newVelocity.z)
return newVelocity
}
private fun getWalkSpeed( vehicle: PokemonEntity ): Double {
val walkspeed = vehicle.runtime.resolveDouble(vehicle.behaviour.moving.walk.walkSpeed)
val movementSpeed = vehicle.attributes.getValue(Attributes.MOVEMENT_SPEED)
val speedModifier = 1.2 * 0.35
return walkspeed * movementSpeed * speedModifier
}
override fun angRollVel(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
if (vehicle !is OrientationControllable) return Vec3.ZERO
val controller = (vehicle as OrientationControllable).orientationController
// turning
val turnMaxRate = 5.5
val turnAccel = 1.0
val turnFriction = 0.75
val targetYawRate = -driver.xxa.toDouble() * turnMaxRate
val currentYawRate = state.yawAngularVelocity.get()
val newYawRate = if (abs(targetYawRate) > 0.001) {
moveToward(currentYawRate, targetYawRate, turnAccel * deltaTime * 20.0)
} else {
moveToward(currentYawRate, 0.0, turnFriction * deltaTime * 20.0)
}
state.yawAngularVelocity.set(newYawRate)
controller.applyGlobalYaw((newYawRate * deltaTime * 20.0).toFloat())
// up-vector alignment framerate-independent
val upAlignmentRatePerTick = 0.1 // fraction of the remaining gap closed per tick
val frameBlend = 1.0 - (1.0 - upAlignmentRatePerTick).pow(deltaTime * 20.0)
alignUpToSurfaceNormal(controller, state.surfaceNormal.get(), frameBlend.toFloat())
// lean into turns (cosmetic local roll)
val maxLeanDeg = 35.0
val leanPerYawRate = 4.0 * 3.0
val leanRatePerTick = 0.25 * 1.5
val desiredLean = (newYawRate * leanPerYawRate).coerceIn(-maxLeanDeg, maxLeanDeg)
val leanFrameBlend = 1.0 - (1.0 - leanRatePerTick).pow(deltaTime * 20.0)
val leanError = controller.roll.angleDifference(desiredLean.toFloat())
controller.rotateRoll((leanError * leanFrameBlend).toFloat())
//yaw, pitch, roll
return Vec3.ZERO
}
private fun moveToward(current: Double, target: Double, maxDelta: Double): Double {
val diff = target - current
return if (abs(diff) <= maxDelta) target else current + maxDelta * diff.sign
}
private fun alignUpToSurfaceNormal(controller: OrientationController, targetUp: Vec3, alignmentBlend: Float) {
if (targetUp.lengthSqr() < 1e-6) return
val targetUpVec = Vector3f(targetUp.x.toFloat(), targetUp.y.toFloat(), targetUp.z.toFloat()).normalize()
controller.updateOrientation { current ->
val currentUp = current.transform(Vector3f(OrientationController.UP), Vector3f())
if (currentUp.lengthSquared() < 1e-6f) return@updateOrientation current
// Full rotation that would exactly align currentUp to targetUp...
val fullCorrection = Quaternionf().rotationTo(currentUp, targetUpVec)
// ...but only take a partial step toward it, so alignment is smooth, not instant.
val steppedCorrection = Quaternionf().slerp(fullCorrection, alignmentBlend)
// Pre-multiply (world-space correction), same pattern applyGlobalYaw uses.
Matrix3f().set(steppedCorrection).mul(current, Matrix3f())
}
}
override fun rotationOnMouseXY(
settings: BoardSettings,
state: BoardState,
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: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun setRideBar(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player
): Float {
return (state.stamina.get() / 1.0f)
}
override fun jumpForce(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return Vec3.ZERO
}
override fun gravity(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return 0.0
}
override fun rideFovMultiplier(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity,
driver: Player
): Float {
return if (state.sprinting.get()) 1.15f else 1.0f
}
override fun useAngVelSmoothing(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun inertia(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Double {
return 1.0
}
override fun shouldRoll(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun turnOffOnGround(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun dismountOnShift(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotateRiderHead(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun maxUpStep(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): Float? {
return if (state.inAir.get()) 0.0f else 1.2f
}
override fun getRideSounds(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): RideSoundSettingsList {
return settings.rideSounds
}
override fun createDefaultState(settings: BoardSettings) = BoardState()
override fun asMoLangValue(
settings: BoardSettings,
state: BoardState,
vehicle: PokemonEntity
): ObjectValue<RidingBehaviour<BoardSettings, BoardState>> {
val canJump = vehicle.runtime.resolveBoolean(settings.canJump ?: globalBoard.canJump!!)
val value = super.asMoLangValue(settings, state, vehicle)
value.functions.put("sprinting") { DoubleValue(state.sprinting.get()) }
value.functions.put("walking") { DoubleValue(state.walking.get()) }
value.functions.put("in_air") { DoubleValue(state.inAir.get() || (state.rideVelocity.get().y >= 0.0 && (vehicle.controllingPassenger as? Player)?.jumping == true && canJump) || (state.rideVelocity.get().y > 0.0)) }
return value
}
}
class BoardSettings : RidingBehaviourSettings {
override val key = BoardBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var infiniteStamina: Expression? = null
private set
var canJump: Expression? = null
private set
var canSprint: Expression? = null
private set
var lookYawLimit: Expression? = null
private set
var speedExpr: Expression? = null
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? = null
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
var staminaExpr: Expression? = null
private set
//Between a one block jump and a six block jump
var jumpExpr: Expression? = null
private set
var handlingExpr: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(canJump)
buffer.writeNullableExpression(canSprint)
buffer.writeNullableExpression(lookYawLimit)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
buffer.writeNullableExpression(canJump)
buffer.writeNullableExpression(canSprint)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
infiniteStamina = buffer.readNullableExpression()
canJump = buffer.readNullableExpression()
canSprint = buffer.readNullableExpression()
lookYawLimit = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
canJump = buffer.readNullableExpression()
canSprint = buffer.readNullableExpression()
}
}
class BoardState : RidingBehaviourState() {
var sprinting = ridingState(false, Side.CLIENT)
var walking = ridingState(false, Side.BOTH)
var sprintToggleable = ridingState(false, Side.CLIENT)
var inAir = ridingState(false, Side.CLIENT)
var jumpTicks = ridingState(0, Side.CLIENT)
var sprintTickTimer = ridingState(0, Side.CLIENT)
var forwardHeldLastTick = ridingState(false, Side.CLIENT)
var surfDist = ridingState(Float.POSITIVE_INFINITY, Side.BOTH)
var surfaceNormal = ridingState(Vec3(0.0, 1.0, 0.0), Side.CLIENT)
var yawAngularVelocity = ridingState(0.0, Side.CLIENT)
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeBoolean(sprinting.get())
buffer.writeBoolean(walking.get())
buffer.writeBoolean(sprintToggleable.get())
buffer.writeBoolean(inAir.get())
buffer.writeInt(jumpTicks.get())
buffer.writeInt(sprintTickTimer.get())
buffer.writeBoolean(forwardHeldLastTick.get())
buffer.writeFloat(surfDist.get())
buffer.writeVec3(surfaceNormal.get())
buffer.writeDouble(yawAngularVelocity.get())
}
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
sprinting.set(buffer.readBoolean(), forced = true)
walking.set(buffer.readBoolean(), forced = true)
sprintToggleable.set(buffer.readBoolean(), forced = true)
inAir.set(buffer.readBoolean(), forced = true)
jumpTicks.set(buffer.readInt(), forced = true)
sprintTickTimer.set(buffer.readInt(), forced = true)
forwardHeldLastTick.set(buffer.readBoolean(), forced = true)
surfDist.set(buffer.readFloat(), forced = true)
surfaceNormal.set(buffer.readVec3(), forced = true)
yawAngularVelocity.set(buffer.readDouble(), forced = true)
}
override fun reset() {
super.reset()
sprinting.set(false, forced = true)
walking.set(false, forced = true)
sprintToggleable.set(false, forced = true)
inAir.set(false, forced = true)
jumpTicks.set(0, forced = true)
sprintTickTimer.set(0, forced = true)
forwardHeldLastTick.set(false, forced = true)
surfDist.set(Float.POSITIVE_INFINITY, forced = true)
surfaceNormal.set(Vec3(0.0, 1.0, 0.0), forced = true)
yawAngularVelocity.set(0.0, forced = true)
}
override fun copy() = BoardState().also {
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
it.sprinting.set(this.sprinting.get(), forced = true)
it.walking.set(this.sprinting.get(), forced = true)
it.sprintToggleable.set(this.sprintToggleable.get(), forced = true)
it.inAir.set(this.inAir.get(), forced = true)
it.jumpTicks.set(this.jumpTicks.get(), forced = true)
it.sprintTickTimer.set(this.sprintTickTimer.get(), forced = true)
it.forwardHeldLastTick.set(this.forwardHeldLastTick.get(), forced = true)
it.surfDist.set(this.surfDist.get(), forced = true)
it.surfaceNormal.set(this.surfaceNormal.get(), forced = true)
it.yawAngularVelocity.set(this.yawAngularVelocity.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is BoardState) return false
if (previous.sprinting.get() != sprinting.get()) return true
if (previous.walking.get() != walking.get()) return true
if (previous.sprintToggleable.get() != sprintToggleable.get()) return true
if (previous.inAir.get() != inAir.get()) return true
if (previous.surfDist.get() != surfDist.get()) return true
return super.shouldSync(previous)
}
}
@@ -0,0 +1,783 @@
/*
* 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.land
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.orientation.OrientationController
import com.cobblemon.mod.common.api.orientation.OrientationController.Companion.UP
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.api.riding.util.DistanceFieldLayer
import com.cobblemon.mod.common.api.riding.util.FieldPrimitive
import com.cobblemon.mod.common.api.riding.util.PrimitiveShape
import com.cobblemon.mod.common.api.riding.util.collectPrimitivesFromBlocks
import com.cobblemon.mod.common.api.riding.util.estimateGradient
import com.cobblemon.mod.common.api.riding.util.sampleField
import com.cobblemon.mod.common.api.riding.util.visualizeDistanceField
import com.cobblemon.mod.common.api.riding.sound.RideSoundSettingsList
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.api.riding.util.DistanceFieldTuning
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.core.Direction
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.*
class ClimbBehaviour : RidingBehaviour<ClimbSettings, ClimbState> {
companion object {
val KEY = cobblemonResource("land/climb")
}
override val key = KEY
override fun getRidingStyle(settings: ClimbSettings, state: ClimbState): RidingStyle {
return RidingStyle.LAND
}
val poseProvider = PoseProvider<ClimbSettings, ClimbState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, state, vehicle ->
return@PoseOption abs(state.rideVelocity.get().horizontalDistance()) > 0.0
})
override fun isActive(
settings: ClimbSettings,
state: ClimbState,
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: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): PoseType {
return this.poseProvider.select(settings, state, vehicle)
}
override fun speed(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVelocity.get().length().toFloat()
}
override fun tick(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
handleSprinting(state, driver)
inAirCheck(state, vehicle)
tickStamina(settings, state, vehicle)
// attachmentNormal: discrete, physics-facing - which face are we touching, used
// for the sticking force (newDownForce) in velocity().
// renderSurfaceNormal: smoothed field-gradient - purely cosmetic, used to slowly
// rotate the model's up vector in angRollVel(). The two are intentionally
// separate and should not be conflated.
updateAttachment(state, vehicle)
updateRenderSurfaceNormal(state, vehicle)
//TODO: should be a config somewhere
val debugVisualizeField = true;
if (debugVisualizeField && !vehicle.level().isClientSide && vehicle.tickCount % 5 == 0) {
visualizeDistanceField(
referenceEntity = vehicle,
center = vehicle.position().add(0.0, (vehicle.bbHeight * 0.5f).toDouble(), 0.0),
layers = listOf(
DistanceFieldLayer(isoValue = 0.0f, color = Vector3f(1f, 0.2f, 0.2f)),
DistanceFieldLayer(isoValue = 1.0f, color = Vector3f(0.2f, 0.6f, 1f))
),
horizontalRadius = 2.0,
verticalRange = 2.0,
sampleSpacing = 0.35,
marchStep = 0.15,
tuning = DistanceFieldTuning(smoothingRange = 0.5f)
)
}
}
/**
* Computes the smoothed field-gradient normal used for rendering only (up-vector
* alignment in angRollVel). Cached here at tick rate since collecting primitives
* and sampling the field is real work - actually applying the rotation happens
* separately at frame rate, same pattern as HorseBehaviour's surfDist/BoardBehaviour's
* surfaceNormal.
*/
fun updateRenderSurfaceNormal(state: ClimbState, vehicle: PokemonEntity) {
val level = vehicle.level()
val center = vehicle.position().add(0.0, (vehicle.bbHeight * 0.5f).toDouble(), 0.0)
val horizontalRadius = 1.5
val verticalRange = 1.5
val searchBox = AABB(
center.x - horizontalRadius, center.y - verticalRange, center.z - horizontalRadius,
center.x + horizontalRadius, center.y + verticalRange, center.z + horizontalRadius
)
val primitives: List<FieldPrimitive> = collectPrimitivesFromBlocks(level, searchBox, PrimitiveShape.ELLIPSOID)
if (primitives.isEmpty()) return
val tuning = DistanceFieldTuning(smoothingRange = 0.5f)
val gradient = estimateGradient(primitives, center, tuning)
state.renderSurfaceNormal.set(gradient)
}
/** Debug viz: draws a short line of particles from the vehicle out along the current attachment normal. */
fun spawnAttachmentNormalParticles(vehicle: PokemonEntity, normal: Vec3) {
val level = vehicle.level()
if (!level.isClientSide) return
if (normal.lengthSqr() < 1e-6) return
val origin = vehicle.position().add(0.0, (vehicle.bbHeight * 0.5f).toDouble(), 0.0)
val length = 1.5
val steps = 15
for (i in 0..steps) {
val t = i.toDouble() / steps
val point = origin.add(normal.scale(length * t))
level.addParticle(ParticleTypes.END_ROD, point.x, point.y, point.z, 0.0, 0.0, 0.0)
}
}
fun inAirCheck(
state: ClimbState,
vehicle: PokemonEntity,
) {
// Check both vertical movement and if there are blocks below.
val posBelow = vehicle.blockPosition().below()
val blockStateBelow = vehicle.level().getBlockState(posBelow)
val isAirOrLiquid = blockStateBelow.isAir || !blockStateBelow.fluidState.isEmpty
val canSupportEntity = blockStateBelow.isFaceSturdy(vehicle.level(), posBelow, Direction.UP)
val standingOnSolid = canSupportEntity && !isAirOrLiquid
// inAir if not on the ground
val inAir = !(vehicle.deltaMovement.y == 0.0 || standingOnSolid)
state.inAir.set(inAir)
}
fun handleSprinting(
state: ClimbState,
driver: Player
) {
if (state.sprinting.get()) {
state.sprinting.set(driver.isSprinting && state.stamina.get() > 0.0f)
} else {
// Only allow sprinting to start if over x percentage of stamina left
val stamSprintPerc = 25.0f
state.sprinting.set(driver.isSprinting && state.stamina.get() > stamSprintPerc / 100.0f)
}
}
fun tickStamina(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
) {
val stam = state.stamina.get()
var newStam = stam
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr)).toFloat() / 20.0f
if (state.sprinting.get()) {
newStam = max(0.0f,stam - stamDrainRate)
} else {
newStam = min(1.0f,stam + stamDrainRate * 4)
}
state.stamina.set(newStam)
}
override fun updatePassengerRotation(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: LivingEntity
) { return }
override fun clampPassengerRotation(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: LivingEntity
) { }
override fun rotation(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return Vec2(vehicle.xRot, vehicle.yRot )
}
/*
* 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.
*
* THIS IS ADAPTED FOR 3D ORIENTATION
*/
fun calcRotAmount(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val walkHandlingBoost = 5
val maxYawDiff = vehicle.runtime.resolveFloat(settings.lookYawLimit)
// Normalize the current rotation diff
val controller = (vehicle as? OrientationControllable)?.orientationController
if (controller == null || controller.orientation == null) return 0.0f
val rotDiff = Mth.wrapDegrees(Mth.wrapDegrees(driver.yRot) - controller.yaw).coerceIn(-maxYawDiff,maxYawDiff)
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 minRotMod = 0.4f // Min speed that the rotation modulation converges towards
val rotDiffMod = ((sqrt(abs(rotDiffNorm)) * (1.0f - minRotMod)) + minRotMod) * rotDiffNorm.sign
// Turn rate should be quick when walking and slower when sprinting.
// Smoothly move between these based on speed
val walkSpeed = getWalkSpeed(vehicle)
val w = max(walkSpeed, vehicle.deltaMovement.horizontalDistance())
val invRelSpeed = (RidingBehaviour.scaleToRange(w, walkSpeed, topSpeed ) - 1.0f) * -1.0f
val turnRate = ((handling.toFloat() / 20.0f) * max(walkHandlingBoost * invRelSpeed, 1.0)).toFloat()
// Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod
val rotAmount = turnSpeed.coerceIn(-abs(rotDiff), abs(rotDiff))
return rotAmount
}
override fun velocity(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
state.rideVelocity.set(calculateRideSpaceVel(settings, state, vehicle, driver))
return state.rideVelocity.get()
}
private fun calculateRideSpaceVel(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val globalHorse: HorseSettings = CobblemonRideSettings.horse
val canSprint = vehicle.runtime.resolveBoolean(settings.canSprint ?: globalHorse.canSprint!!)
val canJump = vehicle.runtime.resolveBoolean(settings.canJump ?: globalHorse.canJump!!)
val jumpForce = vehicle.runtime.resolveDouble(settings.jumpExpr ?: globalHorse.jumpExpr!!) * 0.75
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalHorse.speedExpr!!)
val walkSpeed = getWalkSpeed(vehicle)
val topSpeed = if(canSprint && state.sprinting.get()) rideTopSpeed else walkSpeed
val accelTime = if(state.sprinting.get()) (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHorse.accelerationExpr!!) * 20.0) else 0.5 * 20.0
val accel = topSpeed / accelTime
var activeInput = false
/******************************************************
* Gather the previous velocity and check for horizontal
* collisions
*****************************************************/
var newVelocity = state.rideVelocity.get() //.normalize().scale(vehicle.deltaMovement.horizontalDistance())
/******************************************************
* Gather the previous velocity and check for horizontal
* collisions
*****************************************************/
if (vehicle.horizontalCollision) {
var horizontalVec = Vec3(newVelocity.x, 0.0, newVelocity.z)
horizontalVec = horizontalVec.normalize().scale(min(horizontalVec.length(), 0.3))
newVelocity = Vec3(horizontalVec.x, newVelocity.y, horizontalVec.z)
}
/******************************************************
* Speed up and slow down based on input
*****************************************************/
if (driver.zza != 0.0f) {
// If on a tight turn then do not speed up past half of top speed in order to turn quicker
// Also determine how fast to be slowing down based on how far turned you are
val lookYawLimit = vehicle.runtime.resolveFloat(settings.lookYawLimit ?: globalHorse.lookYawLimit!!)
val percOfMaxTurnSpeed = abs(Mth.wrapDegrees(driver.yRot - vehicle.yRot) / lookYawLimit) * 100.0f
val turnPercThresh = 0.0f
val s = min(((percOfMaxTurnSpeed - turnPercThresh) / (100.0f - turnPercThresh)).pow(1),1.0f)
val effectiveTopSpeed = if (percOfMaxTurnSpeed > turnPercThresh) topSpeed / max(2.0f*s,1.0f) else topSpeed
val turningSlowDown = s * 0.1
//make sure it can't exceed top speed
val forwardInput = when {
driver.zza > 0 && newVelocity.z > effectiveTopSpeed -> 0.0
driver.zza < 0 && newVelocity.z < (-effectiveTopSpeed / 3.0) -> 0.0
else -> driver.zza.sign
}
// Add extra friction if trying to slow down to turn faster
if (newVelocity.z > effectiveTopSpeed) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(turningSlowDown * newVelocity.z.sign, newVelocity.z))
}
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
}
/******************************************************
* Gravity logic
*****************************************************/
val isOnTopSurface = state.attachmentNormal.get() == Vec3(0.0, 1.0, 0.0)
if (isOnTopSurface) {
if (!vehicle.onGround() && state.jumpTicks.get() <= 0) {
val gravity = (9.8 / ( 20.0)) * 0.2 * 0.6
val terminalVel = 2.0
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - gravity, -terminalVel), newVelocity.z)
} else if(vehicle.onGround()) {
newVelocity = Vec3(newVelocity.x, 0.0, newVelocity.z)
}
} else {
// Wall/ceiling - small constant pull to stay stuck, not real gravity.
val stickForce = 0.08
newVelocity = Vec3(newVelocity.x, newVelocity.y - stickForce, newVelocity.z)
}
/******************************************************
* Ground Friction
*****************************************************/
if( (newVelocity.horizontalDistance() > 0 && vehicle.onGround() && !activeInput) || newVelocity.horizontalDistance() > topSpeed) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.03 * newVelocity.z.sign, newVelocity.z))
}
/******************************************************
* Jump Logic
*****************************************************/
if (state.jumpTicks.get() > 0 || (state.jumpTicks.get() >= 0 && driver.jumping && vehicle.onGround() && canJump && driver.deltaMovement.y <= 0.1)) {
// Spread out jumpforce so that variable height jumps are possible
val jumpInputTicks = 6
if (driver.jumping && (state.jumpTicks.get() >= 0 && state.jumpTicks.get() < jumpInputTicks)) {
val appliedJumpForce = ((jumpForce*1.5) / jumpInputTicks) //* (1 - state.jumpTicks.get() / jumpInputTicks)
newVelocity = Vec3(newVelocity.x, newVelocity.y + appliedJumpForce, newVelocity.z)
state.jumpTicks.set(state.jumpTicks.get() + 1)
} else {
// Set delay before next jump is possible after hitting ground
val tickJumpDelay = 3
state.jumpTicks.set(-tickJumpDelay)
}
} else if (vehicle.onGround() && state.jumpTicks.get() < 0) {
// Tick off the delay once reaching the ground
state.jumpTicks.set(state.jumpTicks.get() + 1)
}
// Zero out lateral velocity possibly picked up from a controller transition
newVelocity = Vec3(0.0, newVelocity.y, newVelocity.z)
return newVelocity
}
private fun getWalkSpeed( vehicle: PokemonEntity ): Double {
val walkspeed = vehicle.runtime.resolveDouble(vehicle.behaviour.moving.walk.walkSpeed)
val movementSpeed = vehicle.attributes.getValue(Attributes.MOVEMENT_SPEED)
val speedModifier = 1.2 * 0.35
return walkspeed * movementSpeed * speedModifier
}
override fun angRollVel(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
if (vehicle !is OrientationControllable) return Vec3.ZERO
val controller = vehicle.orientationController
// Smoothly rotate the model's up vector toward the (separately computed,
// smoothed) field-gradient normal. Purely cosmetic - does not affect attachment
// or movement, which are driven by state.attachmentNormal instead.
val upAlignmentRatePerTick = 0.2
val frameBlend = 1.0 - (1.0 - upAlignmentRatePerTick).pow(deltaTime * 20.0)
alignUpToSurfaceNormal(controller, state.renderSurfaceNormal.get(), frameBlend.toFloat())
return Vec3.ZERO
}
/**
* Rotates [controller]'s orientation so its up vector moves a fraction of the way
* toward [targetUp] - partial per call, not instant, so alignment settles smoothly
* rather than snapping every time the target changes.
*/
private fun alignUpToSurfaceNormal(controller: OrientationController, targetUp: Vec3, alignmentBlend: Float) {
if (targetUp.lengthSqr() < 1e-6) return
val targetUpVec = Vector3f(targetUp.x.toFloat(), targetUp.y.toFloat(), targetUp.z.toFloat()).normalize()
controller.updateOrientation { current ->
val currentUp = current.transform(Vector3f(UP), Vector3f())
if (currentUp.lengthSquared() < 1e-6f) return@updateOrientation current
// Full rotation that would exactly align currentUp to targetUp...
val fullCorrection = Quaternionf().rotationTo(currentUp, targetUpVec)
// ...but only take a partial step toward it, so alignment is smooth, not instant.
val steppedCorrection = Quaternionf().slerp(fullCorrection, alignmentBlend)
Matrix3f().set(steppedCorrection).mul(current, Matrix3f())
}
}
override fun rotationOnMouseXY(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
if (vehicle !is OrientationControllable) return Vec3.ZERO
val vehicleController = vehicle.orientationController
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(xInput, 0.0, 0.0)
}
override fun canJump(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun setRideBar(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player
): Float {
return (state.stamina.get() / 1.0f)
}
override fun jumpForce(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return Vec3.ZERO
}
override fun gravity(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return 0.0
}
override fun rideFovMultiplier(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun inertia(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Double {
return 1.0
}
override fun shouldRoll(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun turnOffOnGround(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun dismountOnShift(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotateRiderHead(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun getRideSounds(
settings: ClimbSettings,
state: ClimbState,
vehicle: PokemonEntity
): RideSoundSettingsList {
return settings.rideSounds
}
override fun createDefaultState(settings: ClimbSettings) = ClimbState()
}
class ClimbSettings : RidingBehaviourSettings {
override val key = ClimbBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var canJump = "true".asExpression()
private set
var canSprint = "true".asExpression()
private set
var lookYawLimit = "90.0f".asExpression()
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.4)".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', 'LAND', 0.5, 2.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', 'LAND', 30.0, 10.0)".asExpression()
private set
//Between a one block jump and a six block jump
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'LAND', 1.0, 0.38)".asExpression()
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'LAND', 180.0, 40.0)".asExpression()
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
buffer.writeExpression(canJump)
buffer.writeExpression(canSprint)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
canJump = buffer.readExpression()
canSprint = buffer.readExpression()
}
}
class ClimbState : RidingBehaviourState() {
var sprinting = ridingState(false, Side.CLIENT)
var inAir = ridingState(false, Side.CLIENT)
var jumpTicks = ridingState(0, Side.CLIENT)
// Discrete, physics-facing: which of the 6 faces we're attached to right now.
// Drives newDownForce in velocity(). Set by updateAttachment().
var attachmentNormal = ridingState(Vec3(0.0, 1.0, 0.0), Side.CLIENT)
var attachmentPoint = ridingState(Vec3(0.0, 1.0, 0.0), Side.CLIENT)
// Smoothed, rendering-facing: the field-gradient normal used only to slowly rotate
// the model's visual up vector in angRollVel(). Deliberately separate from
// attachmentNormal - see comments in tick(). Set by updateRenderSurfaceNormal().
var renderSurfaceNormal = ridingState(Vec3(0.0, 1.0, 0.0), Side.CLIENT)
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeBoolean(sprinting.get())
buffer.writeBoolean(inAir.get())
buffer.writeInt(jumpTicks.get())
}
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
sprinting.set(buffer.readBoolean(), forced = true)
inAir.set(buffer.readBoolean(), forced = true)
jumpTicks.set(buffer.readInt(), forced = true)
}
override fun reset() {
super.reset()
sprinting.set(false, forced = true)
inAir.set(false, forced = true)
jumpTicks.set(0, forced = true)
attachmentNormal.set(Vec3(0.0, 1.0, 0.0), forced = true)
attachmentPoint.set(Vec3(0.0, 1.0, 0.0), forced = true)
renderSurfaceNormal.set(Vec3(0.0, 1.0, 0.0), forced = true)
}
override fun copy() = ClimbState().also {
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
it.sprinting.set(this.sprinting.get(), forced = true)
it.inAir.set(this.inAir.get(), forced = true)
it.jumpTicks.set(this.jumpTicks.get(), forced = true)
it.attachmentNormal.set(this.attachmentNormal.get(), forced = true)
it.attachmentPoint.set(this.attachmentNormal.get(), forced = true)
it.renderSurfaceNormal.set(this.renderSurfaceNormal.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is ClimbState) return false
if (previous.sprinting.get() != sprinting.get()) return true
if (previous.inAir.get() != inAir.get()) return true
return super.shouldSync(previous)
}
}
fun updateAttachment(state: ClimbState, vehicle: PokemonEntity) {
val probeMargin = 0.15
val currentFace = AttachmentFace.entries.firstOrNull { it.normal == state.attachmentNormal.get() }
val face = determineAttachmentFace(vehicle, currentFace, probeMargin)
if (face != null) {
state.attachmentNormal.set(face.normal)
}
// face == null means nothing's currently in reach - leave attachmentNormal as
// whatever it last was until the jump/detach state takes over.
}
enum class AttachmentFace(val normal: Vec3) {
UP(Vec3(0.0, 1.0, 0.0)),
DOWN(Vec3(0.0, -1.0, 0.0)),
NORTH(Vec3(0.0, 0.0, -1.0)),
SOUTH(Vec3(0.0, 0.0, 1.0)),
EAST(Vec3(1.0, 0.0, 0.0)),
WEST(Vec3(-1.0, 0.0, 0.0))
}
/** Thin slab test on one face of the vehicle's actual bounding box - true if anything solid is touching that side. */
fun probeFaceContact(vehicle: PokemonEntity, face: AttachmentFace, probeMargin: Double): Boolean {
val box = vehicle.boundingBox
val testBox = when (face) {
AttachmentFace.UP -> AABB(box.minX, box.maxY, box.minZ, box.maxX, box.maxY + probeMargin, box.maxZ)
AttachmentFace.DOWN -> AABB(box.minX, box.minY - probeMargin, box.minZ, box.maxX, box.minY, box.maxZ)
AttachmentFace.NORTH -> AABB(box.minX, box.minY, box.minZ - probeMargin, box.maxX, box.maxY, box.minZ)
AttachmentFace.SOUTH -> AABB(box.minX, box.minY, box.maxZ, box.maxX, box.maxY, box.maxZ + probeMargin)
AttachmentFace.EAST -> AABB(box.maxX, box.minY, box.minZ, box.maxX + probeMargin, box.maxY, box.maxZ)
AttachmentFace.WEST -> AABB(box.minX - probeMargin, box.minY, box.minZ, box.minX, box.maxY, box.maxZ)
}
return !vehicle.level().noCollision(vehicle, testBox)
}
/** Stays on the current face if it's still touching, otherwise scans for a new one. */
fun determineAttachmentFace(vehicle: PokemonEntity, currentFace: AttachmentFace?, probeMargin: Double): AttachmentFace? {
if (currentFace != null && probeFaceContact(vehicle, currentFace, probeMargin)) {
return currentFace
}
return AttachmentFace.entries.firstOrNull { probeFaceContact(vehicle, it, probeMargin) }
}
@@ -42,8 +42,8 @@ abstract class AreaTypeSpawningCondition<T : AreaSpawnablePosition> : SpawningCo
override fun copyFrom(other: SpawningCondition<*>, merger: Merger) {
super.copyFrom(other, merger)
if (other is AreaTypeSpawningCondition) {
merger.mergeSingle(minHeight, other.minHeight)
merger.mergeSingle(maxHeight, other.maxHeight)
minHeight = merger.mergeSingle(minHeight, other.minHeight)
maxHeight = merger.mergeSingle(maxHeight, other.maxHeight)
neededNearbyBlocks = merger.merge(neededNearbyBlocks, other.neededNearbyBlocks)?.toMutableList()
}
}
@@ -46,7 +46,7 @@ abstract class SubmergedTypeSpawningCondition<T : SubmergedSpawnablePosition> :
super.copyFrom(other, merger)
if (other is SubmergedTypeSpawningCondition) {
minDepth = merger.mergeSingle(minDepth, other.minDepth)
maxDepth = merger.mergeSingle(minDepth, other.minDepth)
maxDepth = merger.mergeSingle(maxDepth, other.maxDepth)
fluidIsSource = merger.mergeSingle(fluidIsSource, other.fluidIsSource)
fluid = merger.mergeSingle(fluid, other.fluid)
}
@@ -39,7 +39,7 @@ abstract class SurfaceTypeSpawningCondition<T : SurfaceSpawnablePosition> : Area
super.copyFrom(other, merger)
if (other is SurfaceTypeSpawningCondition) {
minDepth = merger.mergeSingle(minDepth, other.minDepth)
maxDepth = merger.mergeSingle(minDepth, other.minDepth)
maxDepth = merger.mergeSingle(maxDepth, other.maxDepth)
fluid = merger.mergeSingle(fluid, other.fluid)
}
}
@@ -117,6 +117,9 @@ abstract class ShowdownActionResponse(val type: ShowdownActionResponseType) {
data class MoveActionResponse(var moveName: String, var targetPnx: String? = null, var gimmickID: String? = null): ShowdownActionResponse(ShowdownActionResponseType.MOVE) {
override fun isValid(activeBattlePokemon: ActiveBattlePokemon, showdownMoveSet: ShowdownMoveset?, forceSwitch: Boolean): Boolean {
// Ensure that the gimmick ID the player is sending is valid
gimmickID?.let { if (it !in VALID_GIMMICK_IDS) return false }
if (forceSwitch || showdownMoveSet == null) {
return false
}
@@ -168,6 +171,10 @@ data class MoveActionResponse(var moveName: String, var targetPnx: String? = nul
gimmickID = buffer.readNullable { buffer.readString() }
return this
}
companion object {
private val VALID_GIMMICK_IDS = ShowdownMoveset.Gimmick.entries.map { it.id }.toSet()
}
}
data class HealItemActionResponse(var item: String) : ShowdownActionResponse(ShowdownActionResponseType.FORCE_PASS) {
@@ -183,7 +190,8 @@ data class HealItemActionResponse(var item: String) : ShowdownActionResponse(Sho
}
override fun isValid(activeBattlePokemon: ActiveBattlePokemon, showdownMoveSet: ShowdownMoveset?, forceSwitch: Boolean): Boolean {
return !forceSwitch
// Previously checked for !forceSwitch, excepts in the case of a forceSwitch, this couldn't legally be sent anyway.
return false
}
override fun toShowdownString(activeBattlePokemon: ActiveBattlePokemon, showdownMoveSet: ShowdownMoveset?): String {
@@ -37,7 +37,6 @@ import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import java.util.concurrent.CompletableFuture
import net.minecraft.world.entity.LivingEntity
/**
* Format: |move|POKEMON|MOVE|TARGET
@@ -77,7 +76,7 @@ class MoveInstruction(
val pokemonName = userPokemon.getName()
ShowdownInterpreter.lastCauser[battle.battleId] = message
// For Spread targets the message data only gives the pnx strings. So we can't know what pokemon are actually targeted until the previous messages have been interpreted
val spreadTargetPokemon = spreadTargets.map { battle.activePokemon.firstOrNull() { poke -> poke.getPNX() == it }?.battlePokemon }
val spreadTargetPokemon = spreadTargets.map { battle.activePokemon.firstOrNull { poke -> poke.getPNX() == it }?.battlePokemon }
val targetPokemonEntity = targetPokemon?.entity
if (targetPokemonEntity != null) {
@@ -137,10 +136,20 @@ class MoveInstruction(
val subsequentInstructions = instructionSet.findInstructionsCausedBy(this)
val missedTargets = subsequentInstructions.filterIsInstance<MissInstruction>().mapNotNull { it.target }
val faintedTargets = subsequentInstructions.filterIsInstance<FaintInstruction>().map { it.faintingPokemon }
val failed = subsequentInstructions.any { it is FailInstruction }
val failedTargets = subsequentInstructions.filterIsInstance<FailInstruction>().mapNotNull { it.target }
val hitCountInstruction = subsequentInstructions.filterIsInstance<HitCountInstruction>().firstOrNull()
runtime.environment.query.addFunction("target_fainted") { params ->
if (params.params.size == 0) {
return@addFunction DoubleValue(faintedTargets.isNotEmpty())
} else {
val entityUUID = params.getString(0)
return@addFunction DoubleValue(faintedTargets.any { it.entity?.stringUUID == entityUUID })
}
}
runtime.environment.query.addFunction("missed") { params ->
if (params.params.size == 0) {
return@addFunction DoubleValue(missedTargets.isNotEmpty())
@@ -85,6 +85,7 @@ class PartyOverlay : Gui(Minecraft.getInstance()) {
if (HidePartyBinding.shouldHide) {
return false
}
return true
}
}
@@ -558,4 +559,4 @@ class PartyOverlay : Gui(Minecraft.getInstance()) {
}
}
}
}
}
@@ -182,6 +182,7 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
showHorizontalMouse = false
}
VehicleBehaviour.KEY -> {}
BoardBehaviour.KEY -> {}
}
val centerX = minecraft.window.guiScaledWidth / 2
@@ -41,6 +41,8 @@ import kotlin.math.sign
import kotlin.math.sqrt
object MountedCameraRenderer {
private const val MIN_OFFSET_LENGTH = 1.0E-6
private var returnTimer: Float = 0f
private var lastHandledRotationTime: Double = Double.MIN_VALUE
private var frameTime: Double = 0.0
@@ -79,7 +81,7 @@ object MountedCameraRenderer {
val locator = delegate.locatorStates[locatorName] ?: return null
// Get additional offset from poser and add to the eyeHeight offset
val currEyeHeight: Double = Mth.lerp(instance.partialTickTime.toDouble(), eyeHeight, eyeHeightOld)
val currEyeHeight: Double = Mth.lerp(instance.partialTickTime.toDouble(), eyeHeightOld, eyeHeight)
var offset = Vec3(0.0, currEyeHeight - (driver.bbHeight / 2), 0.0)
var eyeOffset = Vec3(0.0, currEyeHeight - (driver.bbHeight / 2), 0.0)
@@ -126,10 +128,10 @@ object MountedCameraRenderer {
} */
val offsetDistance = offset.length()
val offsetDirection = offset.scale(1 / offsetDistance)
val offsetDirection = safeDirection(offset, offsetDistance)
val eyeOffsetDistance = eyeOffset.length()
val eyeOffsetDirection = eyeOffset.scale(1 / eyeOffsetDistance)
val eyeOffsetDirection = safeDirection(eyeOffset, eyeOffsetDistance)
// Use getMaxZoom to calculate clipping
val maxZoom: Double = getMaxZoom(offsetDistance, offsetDirection, pos, instance)
@@ -329,7 +331,7 @@ object MountedCameraRenderer {
val offset = if (thirdPersonReverse && cameraOffsets.containsKey(locatorName + "_reverse")) {
cameraOffsets[locatorName + "_reverse"]!!
} else if (thirdPersonReverse && cameraOffsets.containsKey("seat_default_reverse")) {
cameraOffsets[locatorName + "seat_default_reverse"]!!
cameraOffsets["seat_default_reverse"]!!
} else if (cameraOffsets.containsKey(locatorName)) {
cameraOffsets[locatorName]!!
} else if (cameraOffsets.containsKey("seat_default")) {
@@ -354,6 +356,10 @@ object MountedCameraRenderer {
}
/** Unit direction of [offset], or zero when it's too short to have one (avoids NaN from 0 / 0). */
private fun safeDirection(offset: Vec3, length: Double): Vec3 =
if (length > MIN_OFFSET_LENGTH) offset.scale(1 / length) else Vec3.ZERO
private fun getMaxZoom(maxZoom: Double, directionVector: Vec3, positionVector: Vec3, instance: Camera): Double {
var maxZoom = maxZoom
for (i in 0 .. 7) {
@@ -34,6 +34,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animatio
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
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.client.sound.instances.UIEntitySoundInstance
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
@@ -44,7 +45,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException
import java.util.concurrent.ConcurrentLinkedQueue
import net.minecraft.client.Minecraft
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.commands.arguments.item.ItemParser
import net.minecraft.sounds.SoundEvent
import net.minecraft.world.entity.Entity
@@ -289,7 +289,7 @@ abstract class PosableState : Schedulable {
entity.level().playLocalSound(entity, soundEvent, entity.soundSource, volume, pitch)
}
} else {
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(soundEvent, volume, pitch))
Minecraft.getInstance().soundManager.play(UIEntitySoundInstance(soundEvent, volume, pitch))
}
}
}
@@ -19,6 +19,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.sound.instances.AlphaCrySoundInstance
import com.cobblemon.mod.common.client.sound.instances.UIEntitySoundInstance
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.effectiveName
import com.cobblemon.mod.common.util.genericRuntime
@@ -31,7 +32,6 @@ import net.minecraft.client.Minecraft
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.client.resources.sounds.EntityBoundSoundInstance
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.resources.ResourceLocation
import net.minecraft.sounds.SoundEvent
import net.minecraft.world.entity.Entity
@@ -121,7 +121,7 @@ class BedrockSoundKeyframe(
}
}
} else {
Minecraft.getInstance().soundManager.play(SimpleSoundInstance.forUI(soundEvent, 1F, 1F))
Minecraft.getInstance().soundManager.play(UIEntitySoundInstance(soundEvent))
}
}
}
@@ -29,8 +29,8 @@ class FarfetchdGalarianModel(root: ModelPart) : PokemonPosableModel(root), Heade
override var portraitScale = 2.6F
override var portraitTranslation = Vec3(-0.2, -1.0, 0.0)
override var profileScale = 1.1F
override var profileTranslation = Vec3(-0.1, 0.1, 0.0)
override var profileScale = 0.93F
override var profileTranslation = Vec3(-0.1, 0.36, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
@@ -28,8 +28,8 @@ class FarfetchdModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame,
override var portraitScale = 2.6F
override var portraitTranslation = Vec3(-0.2, -1.0, 0.0)
override var profileScale = 1.1F
override var profileTranslation = Vec3(-0.1, 0.1, 0.0)
override var profileScale = 0.93F
override var profileTranslation = Vec3(-0.1, 0.36, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
@@ -23,8 +23,8 @@ class KabutoModel(root: ModelPart) : PokemonPosableModel(root) {
override var portraitScale = 3.3F
override var portraitTranslation = Vec3(0.0, -3.3, 0.0)
override var profileScale = 1.6F
override var profileTranslation = Vec3(0.0, -0.6, 0.0)
override var profileScale = 1.25F
override var profileTranslation = Vec3(0.0, -0.17, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
@@ -21,8 +21,8 @@ class HoothootModel (root: ModelPart) : PokemonPosableModel(root) {
override var portraitScale = 2.2F
override var portraitTranslation = Vec3(-0.25, -0.9, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.3, 0.0)
override var profileScale = 0.82F
override var profileTranslation = Vec3(0.0, 0.53, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
@@ -29,8 +29,8 @@ class WooperModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.15, -0.65, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.4, 0.0)
override var profileScale = 0.75F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
@@ -29,8 +29,8 @@ class WooperPaldeanModel(root: ModelPart) : PokemonPosableModel(root), HeadedFra
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.15, -0.65, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.4, 0.0)
override var profileScale = 0.75F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonP
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.asExpressionLike
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
@@ -28,6 +29,8 @@ class MasquerainModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame
lateinit var walk: Pose
lateinit var standing: Pose
override fun registerPoses() {
animations["cry"] = "q.bedrock_stateful('masquerain', 'cry')".asExpressionLike()
val blink = quirk { bedrockStateful("masquerain", "blink") }
standing = registerPose(
poseName = "standing",
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonP
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.isInWater
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
@@ -36,6 +37,8 @@ class SurskitModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
val wateroffset = -8
override fun registerPoses() {
animations["cry"] = "q.bedrock_stateful('surskit', 'cry')".asExpressionLike()
val blink = quirk { bedrockStateful("surskit", "blink") }
standing = registerPose(
poseName = "standing",
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonP
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.asExpressionLike
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
@@ -36,6 +37,8 @@ class CombeeModel (root: ModelPart) : PokemonPosableModel(root) {
val shoulderZOffset = 8
override fun registerPoses() {
animations["cry"] = "q.bedrock_stateful('combee', 'cry')".asExpressionLike()
val blink1 = quirk { bedrockStateful("combee", "blink_right") }
val blink2 = quirk { bedrockStateful("combee", "blink_gender") }
val blink3 = quirk { bedrockStateful("combee", "blink_left") }
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonP
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.asExpressionLike
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
@@ -30,6 +31,8 @@ class VespiquenModel (root: ModelPart) : PokemonPosableModel(root) {
lateinit var standing: Pose
override fun registerPoses() {
animations["cry"] = "q.bedrock_stateful('vespiquen', 'cry')".asExpressionLike()
val blink1 = quirk { bedrockStateful("vespiquen", "blink") }
val wingsleep = quirk { bedrockStateful("vespiquen", "sleep_flap") }
@@ -1,62 +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.gen5
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.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SerperiorModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("serperior")
override val head = getPart("head_ai")
override var portraitScale = 2.5F
override var portraitTranslation = Vec3(-0.3, 1.25, 0.0)
override var profileScale = 0.6F
override var profileTranslation = Vec3(0.0, 0.8, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("serperior", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("serperior", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("serperior", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("serperior", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("serperior", "ground_walk")
)
)
}
}
@@ -1,70 +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.gen5
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.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ServineModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("servine")
override val head = getPart("head_ai")
override val rightArm = getPart("arm_right")
override val leftArm = getPart("arm_left")
override val rightLeg = getPart("leg_right")
override val leftLeg = getPart("leg_left")
override var portraitScale = 2.6F
override var portraitTranslation = Vec3(-0.15, 0.75, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("servine", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("servine", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
transformTicks = 10,
animations = arrayOf(bedrock("servine", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("servine", "ground_idle")
)
)
walk = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("servine", "ground_walk")
)
)
}
}
@@ -1,70 +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.gen5
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.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SnivyModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("snivy")
override val head = getPart("head_ai")
override val rightArm = getPart("arm_right")
override val leftArm = getPart("arm_left")
override val rightLeg = getPart("leg_right")
override val leftLeg = getPart("leg_left")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.15, 0.32, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("snivy", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("snivy", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
transformTicks = 10,
animations = arrayOf(bedrock("snivy", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("snivy", "ground_idle")
)
)
walk = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("snivy", "ground_walk")
)
)
}
}
@@ -23,7 +23,7 @@ class CarbinkModel (root: ModelPart) : PokemonPosableModel(root) {
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(0.0, 0.2, 0.0)
override var profileScale = 0.85F
override var profileScale = 0.68F
override var profileTranslation = Vec3(0.0, 0.7, 0.0)
lateinit var standing: CobblemonPose
@@ -1,85 +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.gen6
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.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class GourgeistModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("gourgeist")
override val head = getPart("head")
override var portraitScale = 4.0F
override var portraitTranslation = Vec3(-0.1, 0.6, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.55, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hovering: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("gourgeist", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("gourgeist", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STAND,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("gourgeist", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseType = PoseType.WALK,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("gourgeist", "ground_walk")
)
)
hovering = registerPose(
poseName = "hovering",
poseType = PoseType.HOVER,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("gourgeist", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("gourgeist", "air_fly")
)
)
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("gourgeist", "sleep")
)
)
}
}
@@ -1,77 +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.gen6
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 PumpkabooModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("pumpkaboo")
override val head = getPart("head")
override var portraitScale = 3.5F
override var portraitTranslation = Vec3(0.0, -1.5, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.25, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var battleidle: CobblemonPose
lateinit var sleep: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("pumpkaboo", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("pumpkaboo", "blink") }
val quirk = quirk { bedrockStateful("pumpkaboo", "quirk_idle") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("pumpkaboo", "sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink, quirk),
animations = arrayOf(
singleBoneLook(),
bedrock("pumpkaboo", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("pumpkaboo", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battleidle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("pumpkaboo", "battle_idle")
)
)
}
}
@@ -26,8 +26,8 @@ class ScatterbugModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame
override var portraitScale = 2.6F
override var portraitTranslation = Vec3(-0.2, -1.9, 0.0)
override var profileScale = 1.2F
override var profileTranslation = Vec3(0.0, 0.05, 0.0)
override var profileScale = 0.98F
override var profileTranslation = Vec3(0.0, 0.28, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
@@ -36,8 +36,8 @@ class CharcadetModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame,
override var portraitScale = 1.7F
override var portraitTranslation = Vec3(-0.15, 0.08, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
override var profileScale = 0.58F
override var profileTranslation = Vec3(0.0, 0.91, 0.0)
lateinit var standing: CobblemonPose
lateinit var walking: CobblemonPose
@@ -35,8 +35,8 @@ class QuaquavalModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame,
override var portraitScale = 2.3F
override var portraitTranslation = Vec3(-0.42, 3.7, 0.0)
override var profileScale = 0.32F
override var profileTranslation = Vec3(0.0, 1.24, 0.0)
override var profileScale = 0.36F
override var profileTranslation = Vec3(0.0, 1.19, 0.0)
lateinit var standing: CobblemonPose
lateinit var standing2: CobblemonPose
@@ -1,208 +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.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
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.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.parabolaFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SquawkabillyModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("squawkabilly")
override val head = getPart("head")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
private val tail = getPart("tail")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.2, -0.2, 0.0)
override var profileScale = 0.85F
override var profileTranslation = Vec3(0.0, 0.51, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hovering: Pose
lateinit var flying: Pose
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
override val cryAnimation = CryProvider { bedrockStateful("squawkabilly", "cry") }
val shoulderOffsetX = -1.0
val shoulderOffsetY = 0
override fun registerPoses() {
val blink = quirk { bedrockStateful("squawkabilly", "blink") }
standing = registerPose(
poseName = "standing",
quirks = arrayOf(blink),
poseTypes = PoseType.UI_POSES + PoseType.STAND,
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("squawkabilly", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
quirks = arrayOf(blink),
poseType = PoseType.WALK,
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("squawkabilly", "ground_idle"),
rootPart.translation(
function = parabolaFunction(
peak = -4F,
period = 0.4F
),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Y_AXIS
),
head.translation(
function = sineFunction(
amplitude = (-20F).toRadians(),
period = 1F,
verticalShift = (-10F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { state, _, _ -> state.animationSeconds }
),
leftLeg.rotation(
function = parabolaFunction(
tightness = -20F,
phaseShift = 0F,
verticalShift = (30F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
rightLeg.rotation(
function = parabolaFunction(
tightness = -20F,
phaseShift = 0F,
verticalShift = (30F).toRadians()
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
tail.rotation(
function = sineFunction(
amplitude = (-5F).toRadians(),
period = 1F
),
axis = ModelPartTransformation.X_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
wingFlap(
flapFunction = sineFunction(
amplitude = (-5F).toRadians(),
period = 0.4F,
phaseShift = 0.00F,
verticalShift = (-20F).toRadians()
),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Z_AXIS
),
rightWing.translation(
function = parabolaFunction(
tightness = -10F,
phaseShift = 30F,
verticalShift = (25F).toRadians()
),
axis = ModelPartTransformation.Y_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
leftWing.translation(
function = parabolaFunction(
tightness = -10F,
phaseShift = 30F,
verticalShift = (25F).toRadians()
),
axis = ModelPartTransformation.Y_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
),
)
)
hovering = registerPose(
poseName = "hovering",
quirks = arrayOf(blink),
poseTypes = setOf(PoseType.FLOAT, PoseType.HOVER),
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.9F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Z_AXIS
)
)
)
flying = registerPose(
poseName = "flying",
quirks = arrayOf(blink),
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -14F.toRadians(), period = 0.9F, amplitude = 0.9F),
timeVariable = { state, _, _ -> state.animationSeconds },
axis = ModelPartTransformation.Z_AXIS
)
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("squawkabilly", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(shoulderOffsetX, shoulderOffsetY, 0.0)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("squawkabilly", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(-shoulderOffsetX, shoulderOffsetY, 0.0)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isNotPosedIn(sleep)) bedrockStateful("squawkabilly", "faint") else null
}
@@ -322,8 +322,6 @@ object VaryingModelRepository {
inbuilt("loudred", :: LoudredModel)
inbuilt("exploud", :: ExploudModel)
inbuilt("cryogonal", :: CryogonalModel)
inbuilt("pumpkaboo", :: PumpkabooModel)
inbuilt("gourgeist", :: GourgeistModel)
inbuilt("eiscue", :: EiscueModel)
inbuilt("wooloo", :: WoolooModel)
inbuilt("dubwool", :: DubwoolModel)
@@ -340,9 +338,6 @@ object VaryingModelRepository {
inbuilt("thwackey", ::ThwackeyModel)
inbuilt("rillaboom", ::RillaboomModel)
inbuilt("samurott", ::SamurottModel)
inbuilt("snivy", ::SnivyModel)
inbuilt("servine", ::ServineModel)
inbuilt("serperior", ::SerperiorModel)
inbuilt("slugma", ::SlugmaModel)
inbuilt("magcargo", ::MagcargoModel)
inbuilt("slugma_shiny", ::SlugmaShinyModel)
@@ -402,7 +397,6 @@ object VaryingModelRepository {
inbuilt("bunnelby", ::BunnelbyModel)
inbuilt("arrokuda", ::ArrokudaModel)
inbuilt("barraskewda", ::BarraskewdaModel)
inbuilt("squawkabilly", ::SquawkabillyModel)
inbuilt("ponyta_galarian", ::PonytaGalarianModel)
inbuilt("rapidash_galarian", ::RapidashGalarianModel)
inbuilt("volbeat", ::VolbeatModel)
@@ -0,0 +1,22 @@
/*
* 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.sound.instances
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.client.resources.sounds.SoundInstance
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundSource
/**
* Plays a sound for a Pokémon rendered in a GUI, where there is no entity to take the sound source from.
* Unlike [SimpleSoundInstance.forUI] this uses [SoundSource.NEUTRAL] so the Friendly Creatures slider applies.
*/
class UIEntitySoundInstance(sound: SoundEvent, volume: Float = 1F, pitch: Float = 1F) :
SimpleSoundInstance(sound.location, SoundSource.NEUTRAL, volume, pitch, SoundInstance.createUnseededRandom(),
false, 0, SoundInstance.Attenuation.NONE, 0.0, 0.0, 0.0, true)
@@ -164,6 +164,9 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Pokemon, lang = "experience_multiplier", SERVER)
var experienceMultiplier = 2F
@CobblemonConfigField(Category.Pokemon, lang = "predation_chance", SERVER)
var predationChance = 0.05F
@CobblemonConfigField(Category.Spawning, lang = "pokemon_per_chunk", SERVER)
var pokemonPerChunk = 1F
@@ -1294,16 +1294,7 @@ open class PokemonEntity(
}
private fun showInteractionWheel(player: ServerPlayer, itemStack: ItemStack) {
val canRide = ifRidingAvailableSupply(false) { behaviour, settings, state ->
if (platform != PlatformType.NONE) return@ifRidingAvailableSupply false
if (tethering != null) return@ifRidingAvailableSupply false;
if (seats.isEmpty()) return@ifRidingAvailableSupply false;
if ((owner as? ServerPlayer)?.isInBattle() == true) return@ifRidingAvailableSupply false;
if (this.owner != player && this.passengers.isEmpty()) return@ifRidingAvailableSupply false;
if(pokemon.effectiveScale < Cobblemon.config.minimumRidingScale) return@ifRidingAvailableSupply false;
if(beamMode == 3) return@ifRidingAvailableSupply false;
return@ifRidingAvailableSupply behaviour.isActive(settings, state, this);
}
val canRide = isRideableFor(player)
if (pokemon.getOwnerPlayer() == player) {
val cosmeticItemDefinition = CobblemonCosmeticItems.findValidCosmeticForPokemonAndItem(
player.level().registryAccess(),
@@ -1325,6 +1316,18 @@ open class PokemonEntity(
}
}
fun isRideableFor(player: ServerPlayer): Boolean = ifRidingAvailableSupply(false) canRide@{ behaviour, settings, state ->
if (!player.canInteractWithEntity(this, player.entityInteractionRange())) return@canRide false
if (platform != PlatformType.NONE) return@canRide false
if (tethering != null) return@canRide false
if (seats.isEmpty()) return@canRide false
if ((owner as? ServerPlayer)?.isInBattle() == true) return@canRide false
if (this.owner != player && this.passengers.isEmpty()) return@canRide false
if (pokemon.effectiveScale < Cobblemon.config.minimumRidingScale) return@canRide false
if (beamMode == 3) return@canRide false
return@canRide behaviour.isActive(settings, state, this)
}
override fun getDimensions(pose: Pose): EntityDimensions {
val scale = effects.mockEffect?.scale ?: (form.baseScale * pokemon.effectiveScale)
var result = this.exposedForm.hitbox.scale(scale)
@@ -1606,9 +1609,8 @@ open class PokemonEntity(
|| stack.`is`(CobblemonItemTags.WHITELISTED_ITEMS_TO_HOLD)
fun tryRidingPokemon(player: ServerPlayer): Boolean {
if (pokemon.effectiveScale < Cobblemon.config.minimumRidingScale) {
return false
}
if (!isRideableFor(player)) return false
val event = RidePokemonEvent.Pre(player, this)
CobblemonEvents.RIDE_EVENT_PRE.post(event)
if (!event.isCanceled) {
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.riding.behaviour.types.air.HelicopterSetting
import com.cobblemon.mod.common.api.riding.behaviour.types.air.HoverSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.JetSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.RocketSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.BoardSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.HorseSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleSettings
@@ -35,6 +36,7 @@ class RideSettingsSyncPacket(
val hover: HoverSettings,
val jet: JetSettings,
val rocket: RocketSettings,
val board: BoardSettings,
val horse: HorseSettings,
val minekart: MinekartSettings,
val vehicle: VehicleSettings,
@@ -52,6 +54,7 @@ class RideSettingsSyncPacket(
hover.encode(buffer)
jet.encode(buffer)
rocket.encode(buffer)
board.encode(buffer)
horse.encode(buffer)
minekart.encode(buffer)
vehicle.encode(buffer)
@@ -71,6 +74,7 @@ class RideSettingsSyncPacket(
hover = HoverSettings(),
jet = JetSettings(),
rocket = RocketSettings(),
board = BoardSettings(),
horse = HorseSettings(),
minekart = MinekartSettings(),
vehicle = VehicleSettings(),
@@ -85,6 +89,7 @@ class RideSettingsSyncPacket(
hover.decode(buffer)
jet.decode(buffer)
rocket.decode(buffer)
board.decode(buffer)
horse.decode(buffer)
minekart.decode(buffer)
vehicle.decode(buffer)
@@ -8,9 +8,12 @@
package com.cobblemon.mod.common.net.serverhandling.battle
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.HealItemActionResponse
import com.cobblemon.mod.common.battles.MoveActionResponse
import com.cobblemon.mod.common.exception.IllegalActionChoiceException
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
@@ -25,6 +28,27 @@ object BattleSelectActionsHandler : ServerNetworkPacketHandler<BattleSelectActio
if (!actor.mustChoose) {
return
}
// Battle command injection attempt detection
packet.showdownActionResponses.asSequence()
.flatMap {
when (it) {
is MoveActionResponse -> sequenceOf(it.moveName, it.targetPnx, it.gimmickID)
is HealItemActionResponse -> sequenceOf(it.item)
else -> emptySequence()
}
}
.filterNotNull()
.firstOrNull { field -> field.any(Char::isISOControl) }
?.let {
// Escapes control chars as \uXXXX to prevent forging logs.
val printable = it.replace(Regex("\\p{Cc}")) { "\\u%04x".format(it.value[0].code) }
Cobblemon.LOGGER.warn("Blocked battle command injection from ${player.name.string}: $printable")
actor.sendUpdate(BattleQueueRequestPacket(actor.request!!))
actor.sendUpdate(BattleMakeChoicePacket())
return
}
try {
actor.setActionResponses(packet.showdownActionResponses)
} catch (e: IllegalActionChoiceException) {
@@ -55,6 +55,8 @@ object PlatformEvents {
@JvmField
val CLIENT_PLAYER_LOGOUT = EventObservable<ClientPlayerEvent.Logout>()
@JvmField
val PLAYER_RESPAWN = EventObservable<ServerPlayerEvent.Respawn>()
@JvmField
val PLAYER_DEATH = CancelableObservable<ServerPlayerEvent.Death>()
@JvmField
val RIGHT_CLICK_BLOCK = CancelableObservable<ServerPlayerEvent.RightClickBlock>()
@@ -50,6 +50,11 @@ interface ServerPlayerEvent {
*/
data class Logout(override val player: ServerPlayer) : ServerPlayerEvent
/**
* Fired when the [player] respawns (either by coming back from the end or dying).
*/
data class Respawn(override val player: ServerPlayer) : ServerPlayerEvent
/**
* Fired when the [player] dies.
* If canceled the death will be prevented but healing is required in order to not be stuck in a loop.
@@ -135,17 +135,18 @@ internal object PropertiesCompletionProvider : DataRegistry {
private fun addDefaults() {
this.inject(setOf("level", "lvl", "l"), setOf("1", "${Cobblemon.config.maxPokemonLevel}") )
this.inject(setOf("shiny", "s"), setOf("yes", "no"))
this.inject(setOf("alpha", "is_alpha"), setOf("yes", "no"))
this.inject(setOf("gender"), Gender.entries.map { it.name.lowercase() })
this.inject(setOf("friendship"), setOf("0", Cobblemon.config.maxPokemonFriendship.toString()))
this.inject(setOf("fullness"), setOf("0", "255"))
this.inject(setOf("pokeball"), PokeBalls.all().map { it.name.simplify() })
this.inject(setOf("nature"), Natures.all().map { it.name.simplify() })
this.inject(setOf("ability"), Abilities.all().map { if (it.name.asIdentifierDefaultingNamespace().namespace == Cobblemon.MODID) it.name.asIdentifierDefaultingNamespace().path else it.name })
this.inject(setOf("dmax"), setOf("0", Cobblemon.config.maxDynamaxLevel.toString()))
this.inject(setOf("gmax"), setOf("yes", "no"))
this.inject(setOf("dmax_level", "dmax"), setOf("0", Cobblemon.config.maxDynamaxLevel.toString()))
this.inject(setOf("gmax_factor", "gmax"), setOf("yes", "no"))
this.inject(setOf("type", "elemental_type"), ElementalTypes.all().map { it.name })
this.inject(setOf("tera_type", "tera"), TeraTypes.map { it.id.simplify() })
this.inject(setOf("tradeable"), setOf("yes", "no"))
this.inject(setOf("tradeable", "tradable"), setOf("yes", "no"))
this.inject(setOf("originaltrainer", "ot"), setOf(""))
this.inject(setOf("originaltrainertype", "ottype"), setOf("None", "Player", "NPC"))
this.inject(setOf("nickname", "nick"), setOf(""))
@@ -17,12 +17,7 @@ import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.
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.api.riding.behaviour.types.land.HorseBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.HorseSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.*
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.*
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonDeserializationContext
@@ -50,7 +45,9 @@ object RidingBehaviourSettingsAdapter : JsonDeserializer<RidingBehaviourSettings
MinekartBehaviour.KEY to MinekartSettings::class.java,
HoverBehaviour.KEY to HoverSettings::class.java,
RocketBehaviour.KEY to RocketSettings::class.java,
BoardBehaviour.KEY to BoardSettings::class.java,
SubmarineBehaviour.KEY to SubmarineSettings::class.java,
ClimbBehaviour.KEY to ClimbSettings::class.java,
CompositeBehaviour.KEY to CompositeSettings::class.java,
/*
@@ -26,5 +26,6 @@ object CobblemonGameRules {
val SHINY_STARTERS: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doShinyStarters", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@JvmField
val HEALERS_HEAL_PC: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersHealPC", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@JvmField
val DO_POKEMON_PREDATION: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doPokemonPredation", GameRules.Category.MOBS, BooleanRuleInvoker.`cobblemon$create`(true))
}
@@ -0,0 +1,90 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_actor",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/moves/watershuriken"
}
},
"curves": {
"variable.rsize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 1, 1, 1, 1, 1, 1]
}
},
"events": {
"trail": {
"particle_effect": {
"effect": "cobblemon:watershuriken_actortrail",
"type": "particle"
}
},
"hit": {
"particle_effect": {
"effect": "cobblemon:watershuriken_target",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.25
},
"minecraft:emitter_shape_disc": {
"offset": [0, 0.02, 0.1],
"radius": 0.5,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.35
},
"minecraft:particle_lifetime_events": {
"timeline": {
"0.00": "trail",
"0.06": "trail",
"0.12": "trail",
"0.18": "trail",
"0.24": "trail",
"0.30": "trail",
"0.34": "hit"
}
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_motion_parametric": {
"relative_position": ["-v.target_deltax*(v.particle_age / v.particle_lifetime)", "(v.target_deltay*(v.particle_age / v.particle_lifetime))", "-v.target_deltaz*(v.particle_age / v.particle_lifetime)"]
},
"minecraft:particle_appearance_billboard": {
"size": ["0.4*v.rsize", "0.4*v.rsize"],
"facing_camera_mode": "lookat_direction",
"direction": {
"mode": "custom",
"custom_direction": [0, 0, -1]
},
"uv": {
"texture_width": 60,
"texture_height": 15,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [15, 15],
"step_UV": [15, 0],
"frames_per_second": 24,
"max_frame": 4,
"loop": true
}
}
}
}
}
}
@@ -0,0 +1,91 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_actoralt",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/moves/watershuriken"
}
},
"curves": {
"variable.rsize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 1, 1, 1, 1, 1, 1]
}
},
"events": {
"trail": {
"particle_effect": {
"effect": "cobblemon:watershuriken_actortrail",
"type": "particle"
}
},
"hit": {
"particle_effect": {
"effect": "cobblemon:watershuriken_target",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 7,
"max_particles": 3
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.4
},
"minecraft:emitter_shape_disc": {
"offset": [0, 0.02, 0.1],
"radius": 0.5,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.35
},
"minecraft:particle_lifetime_events": {
"timeline": {
"0.00": "trail",
"0.06": "trail",
"0.12": "trail",
"0.18": "trail",
"0.24": "trail",
"0.30": "trail",
"0.34": "hit"
}
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_motion_parametric": {
"relative_position": ["-(v.target_deltax+((v.particle_random_1-0.5)*2))*(v.particle_age / v.particle_lifetime)", "(v.target_deltay+((v.particle_random_2-0.5)*2))*(v.particle_age / v.particle_lifetime)", "-v.target_deltaz*(v.particle_age / v.particle_lifetime)"]
},
"minecraft:particle_appearance_billboard": {
"size": ["0.4*v.rsize", "0.4*v.rsize"],
"facing_camera_mode": "lookat_direction",
"direction": {
"mode": "custom",
"custom_direction": [0, 0, -1]
},
"uv": {
"texture_width": 60,
"texture_height": 15,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [15, 15],
"step_UV": [15, 0],
"frames_per_second": 24,
"max_frame": 4,
"loop": true
}
}
}
}
}
}
@@ -0,0 +1,86 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_actorhor",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/moves/watershuriken"
}
},
"curves": {
"variable.rsize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 1, 1, 1, 1, 1, 1]
}
},
"events": {
"trail": {
"particle_effect": {
"effect": "cobblemon:watershuriken_actortrail",
"type": "particle"
}
},
"hit": {
"particle_effect": {
"effect": "cobblemon:watershuriken_target",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.25
},
"minecraft:emitter_shape_disc": {
"offset": [0, 0.02, 0.1],
"radius": 0.5,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.35
},
"minecraft:particle_lifetime_events": {
"timeline": {
"0.00": "trail",
"0.06": "trail",
"0.12": "trail",
"0.18": "trail",
"0.24": "trail",
"0.30": "trail",
"0.34": "hit"
}
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_motion_parametric": {
"relative_position": ["-v.target_deltax*(v.particle_age / v.particle_lifetime)", "(v.target_deltay*(v.particle_age / v.particle_lifetime))", "-v.target_deltaz*(v.particle_age / v.particle_lifetime)"]
},
"minecraft:particle_appearance_billboard": {
"size": ["0.4*v.rsize", "0.4*v.rsize"],
"facing_camera_mode": "emitter_transform_xz",
"uv": {
"texture_width": 60,
"texture_height": 15,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [15, 15],
"step_UV": [15, 0],
"frames_per_second": 24,
"max_frame": 4,
"loop": true
}
}
}
}
}
}
@@ -0,0 +1,63 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_actortrail",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_water"
}
},
"curves": {
"variable.scale": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 0]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 1
},
"minecraft:emitter_shape_point": {
"direction": ["v.particle_random_1-0.5", "v.particle_random_2-0.25", -3]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.3, 0.6)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": 8,
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, -5, 0],
"linear_drag_coefficient": 8
},
"minecraft:particle_appearance_billboard": {
"size": ["0.22 * variable.scale", "0.22 * variable.scale"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 24],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 16,
"max_frame": 4
}
}
},
"minecraft:particle_motion_collision": {
"collision_radius": 0.02
},
"minecraft:particle_appearance_tinting": {
"color": [0.61176, 0.87451, 1, 1]
}
}
}
}
@@ -0,0 +1,86 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_actorvert",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/moves/watershuriken"
}
},
"curves": {
"variable.rsize": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 1, 1, 1, 1, 1, 1]
}
},
"events": {
"trail": {
"particle_effect": {
"effect": "cobblemon:watershuriken_actortrail",
"type": "particle"
}
},
"hit": {
"particle_effect": {
"effect": "cobblemon:watershuriken_target",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_initialization": {
"creation_expression": "v.target_deltaz=5;"
},
"minecraft:emitter_rate_instant": {
"num_particles": 1
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.25
},
"minecraft:emitter_shape_disc": {
"offset": [0, 0.02, 0.1],
"radius": 0.5,
"direction": "outwards"
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.35
},
"minecraft:particle_lifetime_events": {
"timeline": {
"0.00": "trail",
"0.06": "trail",
"0.12": "trail",
"0.18": "trail",
"0.24": "trail",
"0.30": "trail",
"0.34": "hit"
}
},
"minecraft:particle_initial_spin": {
"rotation": "math.random_integer(0,3)*90"
},
"minecraft:particle_motion_parametric": {
"relative_position": ["-v.target_deltax*(v.particle_age / v.particle_lifetime)", "(v.target_deltay*(v.particle_age / v.particle_lifetime))", "-v.target_deltaz*(v.particle_age / v.particle_lifetime)"]
},
"minecraft:particle_appearance_billboard": {
"size": ["0.4*v.rsize", "0.4*v.rsize"],
"facing_camera_mode": "emitter_transform_yz",
"uv": {
"texture_width": 60,
"texture_height": 15,
"flipbook": {
"base_UV": [0, 0],
"size_UV": [15, 15],
"step_UV": [15, 0],
"frames_per_second": 24,
"max_frame": 4,
"loop": true
}
}
}
}
}
}
@@ -0,0 +1,69 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_target",
"basic_render_parameters": {
"material": "particles_alpha",
"texture": "textures/particles/generic/impact/impact_water"
}
},
"curves": {
"variable.scale": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [1, 0]
}
},
"events": {
"event": {
"particle_effect": {
"effect": "cobblemon:watershuriken_targetspark",
"type": "particle"
}
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": 240,
"max_particles": 14
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.1
},
"minecraft:emitter_lifetime_events": {
"creation_event": "event"
},
"minecraft:emitter_shape_point": {},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "math.random(0.3, 0.6)"
},
"minecraft:particle_initial_spin": {
"rotation": "math.round(v.particle_random_4*3)*90"
},
"minecraft:particle_initial_speed": "math.random(9,17)",
"minecraft:particle_motion_dynamic": {
"linear_drag_coefficient": 5
},
"minecraft:particle_appearance_billboard": {
"size": ["0.3 * variable.scale", "0.3 * variable.scale"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 56,
"flipbook": {
"base_UV": [0, 16],
"size_UV": [8, 8],
"step_UV": [0, 8],
"frames_per_second": 16,
"max_frame": 5
}
}
},
"minecraft:particle_appearance_tinting": {
"color": [0.61176, 0.87451, 1, 1]
}
}
}
}
@@ -0,0 +1,62 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:watershuriken_targetspark",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/vanilla/critical_hit"
}
},
"curves": {
"variable.bitespark": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 1, 0.88, 0.66, 0.35, -0.05]
}
},
"components": {
"minecraft:emitter_rate_instant": {
"num_particles": 7
},
"minecraft:emitter_lifetime_once": {
"active_time": 1
},
"minecraft:emitter_shape_point": {
"offset": [0, 0, -0.25],
"direction": ["v.particle_random_1-0.5", "v.particle_random_2-0.25", "v.particle_random_3-0.5"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": "0.5-(v.particle_random_4*0.1)"
},
"minecraft:particle_initial_speed": "math.random(1.75,3.55)*3",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, -5, 0],
"linear_drag_coefficient": 4
},
"minecraft:particle_appearance_billboard": {
"size": ["0.125*v.bitespark", "0.125*v.bitespark"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 8,
"uv": [0, 0],
"uv_size": [7, 7]
}
},
"minecraft:particle_motion_collision": {
"collision_radius": 0.01
},
"minecraft:particle_appearance_tinting": {
"color": {
"interpolant": "v.particle_age / v.particle_lifetime",
"gradient": {
"0.0": "#FF51D8FF",
"1.0": "#FF0076FF"
}
}
}
}
}
}
@@ -37,10 +37,10 @@
"rotation": [0, -7.5, 0]
},
"tail2": {
"rotation": [30, 0, 0]
"rotation": ["30-math.sin(q.anim_time*90*2-60)*-3", 0, 0]
},
"tail3": {
"rotation": [12.5, 0, 0]
"rotation": ["12.5-math.sin(q.anim_time*90*2-120)*-3", 0, 0]
},
"leg_right": {
"rotation": [0, 5, 0]
@@ -53,6 +53,22 @@
},
"wings_open": {
"scale": 0
},
"torso": {
"rotation": ["-math.sin(q.anim_time*90*2-90)*1", 0, "math.sin(q.anim_time*90*1-90)*1"],
"position": [0, "math.sin(q.anim_time*90*2)*0.1", 0]
},
"wing_closed_left": {
"rotation": ["-0-math.sin(q.anim_time*90*2-150)*1", 0, 0]
},
"wing_closed_right": {
"rotation": ["-0-math.sin(q.anim_time*90*2-150)*1", 0, 0]
},
"neck": {
"rotation": ["-math.sin(q.anim_time*90*2-180)*1", 0, 0]
},
"head": {
"rotation": ["-math.sin(q.anim_time*90*2-90)*-2", 0, "math.sin(q.anim_time*90*1-60)*-1"]
}
}
},
@@ -111,6 +127,30 @@
}
}
},
"torso": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.1667": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
@@ -118,19 +158,15 @@
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [85, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [85, 0, 0],
"post": [72.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [85, 0, 0],
"0.8333": {
"post": [52.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.1667": {
@@ -138,6 +174,32 @@
"lerp_mode": "catmullrom"
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.5833": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.75": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.5833": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.75": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
}
},
"sound_effects": {
@@ -203,6 +265,546 @@
"position": [-0.1, 0, -0.1]
}
}
},
"animation.spearow.hold_item": {
"loop": true,
"bones": {
"jaw": {
"rotation": [30, 0, 0]
}
}
},
"animation.spearow.ground_walk": {
"loop": true,
"animation_length": 0.75,
"bones": {
"torso": {
"rotation": ["1-math.cos(q.anim_time*90*16/3*2)*-2", "-math.sin(q.anim_time*90*16/3+60)*3", "-1+math.sin(q.anim_time*90*16/3+30)*-4"],
"position": [0, "math.sin(q.anim_time*90*16/3*2)*0.2", 0]
},
"wings_open": {
"scale": 0
},
"wing_closed_left": {
"rotation": [3, 0, 0]
},
"wing_closed_right": {
"rotation": [3, 0, 0]
},
"tail2": {
"rotation": ["22-math.cos(q.anim_time*90*16/3*2)*5", 0, 0]
},
"tail3": {
"rotation": ["5-math.cos(q.anim_time*90*16/3*2)*5", 0, 0]
},
"neck": {
"rotation": {
"0.0": ["-math.cos(q.anim_time*90*16/3*2)*-12.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"],
"0.125": ["-math.cos(q.anim_time*90*16/3*2)*-9.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"],
"0.1667": ["-math.cos(q.anim_time*90*16/3*2)*-12.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"],
"0.375": ["-math.cos(q.anim_time*90*16/3*2)*-12.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"],
"0.5": ["-math.cos(q.anim_time*90*16/3*2)*-9.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"],
"0.5417": ["-math.cos(q.anim_time*90*16/3*2)*-12.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"]
},
"position": {
"0.0": [0, "math.cos(q.anim_time*90*16/3*2)*0.2", 0],
"0.0417": [0, -0.075, 0.025],
"0.0833": [0, "-0.2+math.cos(q.anim_time*90*16/3*2)*0.2", -0.2],
"0.125": [0, -0.22, -0.17],
"0.1667": [0, -0.21, -0.185],
"0.375": [0, "math.cos(q.anim_time*90*16/3*2)*0.2", 0],
"0.4167": [0, -0.075, 0.025],
"0.4583": [0, "-0.2+math.cos(q.anim_time*90*16/3*2)*0.2", -0.2],
"0.5": [0, -0.22, -0.17],
"0.5417": [0, -0.21, -0.185],
"0.75": [0, "math.cos(q.anim_time*90*16/3*2)*0.2", 0]
}
},
"head": {
"rotation": ["5-math.cos(q.anim_time*90*16/3*2)*18", 0, 0],
"position": [0, 0, "-0.2+math.cos(q.anim_time*90*16/3*2)*0.3"]
},
"scruff_left": {
"rotation": [0, "-0-math.cos(q.anim_time*90*16/3*2-30)*7", 0]
},
"scruff_right": {
"rotation": [0, "0+math.cos(q.anim_time*90*16/3*2-30)*7", 0]
},
"scruff_top_right": {
"rotation": ["-0-math.cos(q.anim_time*90*16/3*2-30)*5", 0, 0]
},
"scruff_bottom": {
"rotation": ["-0-math.cos(q.anim_time*90*16/3*2)*-12", 0, 0]
},
"leg_left": {
"rotation": {
"0.0": [25, -17.5, 0],
"0.125": {
"pre": [21.25, -12.5, 0],
"post": [21.25, -12.5, 0],
"lerp_mode": "catmullrom"
},
"0.375": [-40, -5, 0],
"0.75": [25, -17.5, 0]
},
"position": {
"0.0": [0.3, 0.1, 0.6],
"0.0417": [0.23, 0.25, 0.71],
"0.125": {
"pre": [0, 0.68, -0.08],
"post": [0, 0.68, -0.08],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0.97, -1.41],
"lerp_mode": "catmullrom"
},
"0.375": [0, -0.5, -2.15],
"0.5": [0, -0.19, -1.02],
"0.5833": [0, -0.07, -0.3],
"0.625": [0, -0.02, 0.21],
"0.7083": [0.1, 0.215, 0.43],
"0.75": [0.3, 0.1, 0.6]
}
},
"leg_left2": {
"rotation": {
"0.0": [0, 0, 0],
"0.125": {
"pre": [-30.83, 0, 0],
"post": [-30.83, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-2.65, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": [12.5, 0, 0],
"0.75": [0, 0, 0]
}
},
"foot_left": {
"rotation": {
"0.0": [27.5, 0, -5],
"0.125": {
"pre": [20.17, 0, 0],
"post": [20.17, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [12.596, 0.6637, -1.3486],
"lerp_mode": "catmullrom"
},
"0.375": [28, 0, 0],
"0.625": [-7.33, 0, 0],
"0.75": [27.5, 0, -5]
},
"position": {
"0.0": [0, 0.25, 0],
"0.125": [0, 0, 0],
"0.375": [0, 0, 0],
"0.625": [0, 0.17, 0],
"0.75": [0, 0.25, 0]
}
},
"toe_back_left": {
"rotation": {
"0.0": [-20, 0, 0],
"0.2083": {
"pre": [-8.33, 0, 0],
"post": [-8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [-20, 0, 0]
}
},
"toe_inner_left": {
"rotation": {
"0.0": [-55, 10, -7.5],
"0.125": {
"pre": [7.5, 15, 0],
"post": [7.5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, 15, 0],
"0.625": [0, 15, 0],
"0.75": [-55, 10, -7.5]
},
"position": {
"0.0": [0, -0.75, 1.35],
"0.125": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [0, -0.75, 1.35]
}
},
"toe_outer_left": {
"rotation": {
"0.0": [-51.5, -2.5, 10],
"0.125": {
"pre": [5, -15, 0],
"post": [5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, -15, 0],
"0.625": [0, -15, 0],
"0.75": [-51.5, -2.5, 10]
},
"position": {
"0.0": [0, -0.75, 1.35],
"0.125": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [0, -0.75, 1.35]
}
},
"leg_right": {
"rotation": {
"0.0": [-40, 5, 0],
"0.375": [25, 17.5, 0],
"0.5": {
"pre": [21.25, 12.5, 0],
"post": [21.25, 12.5, 0],
"lerp_mode": "catmullrom"
},
"0.75": [-40, 5, 0]
},
"position": {
"0.0": [0, -0.5, -2.15],
"0.125": [0, -0.19, -1.02],
"0.2083": [0, -0.07, -0.3],
"0.25": [0, -0.02, 0.21],
"0.3333": [-0.1, 0.215, 0.43],
"0.375": [-0.3, 0.1, 0.6],
"0.4167": [-0.23, 0.25, 0.71],
"0.5": {
"pre": [0, 0.68, -0.08],
"post": [0, 0.68, -0.08],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [0, 0.97, -1.41],
"lerp_mode": "catmullrom"
},
"0.75": [0, -0.5, -2.15]
}
},
"leg_right2": {
"rotation": {
"0.0": [12.5, 0, 0],
"0.375": [0, 0, 0],
"0.5": {
"pre": [-30.83, 0, 0],
"post": [-30.83, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-2.65, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": [12.5, 0, 0]
}
},
"foot_right": {
"rotation": {
"0.0": [28, 0, 0],
"0.25": [-7.33, 0, 0],
"0.375": [27.5, 0, 5],
"0.5": {
"pre": [20.17, 0, 0],
"post": [20.17, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [12.596, -0.6637, 1.3486],
"lerp_mode": "catmullrom"
},
"0.75": [28, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0.17, 0],
"0.375": [0, 0.25, 0],
"0.5": [0, 0, 0],
"0.75": [0, 0, 0]
}
},
"toe_back_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [-20, 0, 0],
"0.5833": {
"pre": [-8.33, 0, 0],
"post": [-8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, 0, 0]
}
},
"toe_inner_right": {
"rotation": {
"0.0": [0, -15, 0],
"0.25": [0, -15, 0],
"0.375": [-55, -10, 7.5],
"0.5": {
"pre": [7.5, -15, 0],
"post": [7.5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, -15, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [0, -0.75, 1.35],
"0.5": [0, 0, 0],
"0.75": [0, 0, 0]
}
},
"toe_outer_right": {
"rotation": {
"0.0": [0, 15, 0],
"0.25": [0, 15, 0],
"0.375": [-51.5, 2.5, -10],
"0.5": {
"pre": [5, 15, 0],
"post": [5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, 15, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [0, -0.75, 1.35],
"0.5": [0, 0, 0],
"0.75": [0, 0, 0]
}
}
}
},
"animation.spearow.air_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"position": ["-math.sin(q.anim_time*90*3-45)*0.5", "math.sin(q.anim_time*90*6-45)*1.5", "math.sin(q.anim_time*90*6-45)*1/2"]
},
"torso": {
"rotation": ["-math.sin(q.anim_time*90*6-120)*-4", 0, "math.sin(q.anim_time*90*3-90)*4"]
},
"wing_open_left": {
"rotation": ["-math.sin(q.anim_time*90*6-90)*6", 0, "math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_open_left2": {
"rotation": [0, 0, "20+math.sin(q.anim_time*90*6-45)*30"]
},
"wing_open_left3": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*6-75)*30"]
},
"wing_open_right": {
"rotation": ["-math.sin(q.anim_time*90*6-90)*6", 0, "-math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_open_right2": {
"rotation": [0, 0, "-20-math.sin(q.anim_time*90*6-45)*30"]
},
"wing_open_right3": {
"rotation": [0, 0, "-0-math.sin(q.anim_time*90*6-75)*30"]
},
"tail2": {
"rotation": ["-math.sin(q.anim_time*90*6-30)*5", 0, 0]
},
"tail3": {
"rotation": ["-math.sin(q.anim_time*90*6-90)*5", 0, 0]
},
"neck": {
"rotation": ["5-math.sin(q.anim_time*90*6-140)*-1", 0, "math.sin(q.anim_time*90*3-00)*-1"]
},
"head": {
"rotation": ["-math.sin(q.anim_time*90*6-110)*3", 0, "math.sin(q.anim_time*90*3-120)*-2"]
},
"scruff_left": {
"rotation": [0, "-0-math.sin(q.anim_time*90*6-170)*4", 0]
},
"scruff_right": {
"rotation": [0, "0+math.sin(q.anim_time*90*6-170)*4", 0]
},
"scruff_top_right": {
"rotation": ["-0-math.sin(q.anim_time*90*6-210)*6", 0, 0]
},
"scruff_bottom": {
"rotation": ["-0-math.sin(q.anim_time*90*6-170)*3", 0, 0]
},
"leg_left": {
"rotation": [50, 0, 0]
},
"leg_left2": {
"rotation": [-100, 0, 0]
},
"foot_left": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", -10, "math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_left": {
"rotation": [-27.5, 0, 0]
},
"toe_inner_left": {
"rotation": [37.5, 0, 0]
},
"toe_outer_left": {
"rotation": [37.5, 0, 0]
},
"leg_right": {
"rotation": [50, 0, 0]
},
"leg_right2": {
"rotation": [-100, 0, 0]
},
"foot_right": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", 10, "-math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_right": {
"rotation": [-27.5, 0, 0]
},
"toe_inner_right": {
"rotation": [37.5, 0, 0]
},
"toe_outer_right": {
"rotation": [37.5, 0, 0]
}
},
"timeline": {
"0.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"1.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"3.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"4.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};"
}
},
"animation.spearow.air_fly": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"position": ["-math.sin(q.anim_time*90*3-45)*0.5", "math.sin(q.anim_time*90*6-45)*1.5", "math.sin(q.anim_time*90*6-45)*1/2"]
},
"torso": {
"rotation": ["15-math.sin(q.anim_time*90*6-120)*-1.5", 0, "math.sin(q.anim_time*90*3-90)*4"]
},
"wing_open_left": {
"rotation": ["-math.sin(q.anim_time*90*6-90)*6", 0, "math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_open_left2": {
"rotation": [0, 0, "20+math.sin(q.anim_time*90*6-45)*30"]
},
"wing_open_left3": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*6-75)*30"]
},
"wing_open_right": {
"rotation": ["-math.sin(q.anim_time*90*6-90)*6", 0, "-math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_open_right2": {
"rotation": [0, 0, "-20-math.sin(q.anim_time*90*6-45)*30"]
},
"wing_open_right3": {
"rotation": [0, 0, "-0-math.sin(q.anim_time*90*6-75)*30"]
},
"tail": {
"rotation": [-10, 0, 0]
},
"tail2": {
"rotation": ["-math.sin(q.anim_time*90*6-30)*5", 0, 0]
},
"tail3": {
"rotation": ["-math.sin(q.anim_time*90*6-90)*5", 0, 0]
},
"neck": {
"rotation": ["5-math.sin(q.anim_time*90*6-140)*-1", 0, "math.sin(q.anim_time*90*3-00)*-1"]
},
"head_ai": {
"rotation": [5, 0, 0]
},
"head": {
"rotation": ["-7.5-math.sin(q.anim_time*90*6-110)*3", 0, "math.sin(q.anim_time*90*3-120)*-2"]
},
"scruff_left": {
"rotation": [0, "-0-math.sin(q.anim_time*90*6-170)*4", 0]
},
"scruff_right": {
"rotation": [0, "0+math.sin(q.anim_time*90*6-170)*4", 0]
},
"scruff_top_right": {
"rotation": ["-0-math.sin(q.anim_time*90*6-210)*6", 0, 0]
},
"scruff_bottom": {
"rotation": ["-0-math.sin(q.anim_time*90*6-170)*3", 0, 0]
},
"leg_left": {
"rotation": [50, 0, 0]
},
"leg_left2": {
"rotation": [-100, 0, 0]
},
"foot_left": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", -10, "math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_left": {
"rotation": [-27.5, 0, 0]
},
"toe_inner_left": {
"rotation": [37.5, 0, 0]
},
"toe_outer_left": {
"rotation": [37.5, 0, 0]
},
"leg_right": {
"rotation": [50, 0, 0]
},
"leg_right2": {
"rotation": [-100, 0, 0]
},
"foot_right": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", 10, "-math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_right": {
"rotation": [-27.5, 0, 0]
},
"toe_inner_right": {
"rotation": [37.5, 0, 0]
},
"toe_outer_right": {
"rotation": [37.5, 0, 0]
}
},
"timeline": {
"0.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"1.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"3.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"4.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};"
}
}
}
}
@@ -217,7 +217,7 @@
}
}
},
"animation.raichu_cap.water_swim": {
"animation.raichu_cap.water_surface_swim": {
"loop": true,
"animation_length": 1,
"bones": {
@@ -2,6 +2,312 @@
"format_version": "1.8.0",
"animations": {
"animation.ninetales.ground_idle": {
"loop": true,
"bones": {
"body": {
"position": [0, -0.3, 0]
},
"torso": {
"rotation": ["5+math.sin(q.anim_time*90*1-0)*0.5", 0, "0-math.sin(q.anim_time*90*0.5-30)*0.5"]
},
"chest": {
"rotation": ["-4.8+math.sin(q.anim_time*90*1-30)*0.5", 0, -1.2]
},
"neck": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1-60)*1", 0, 0]
},
"neck_fur_left2": {
"rotation": [0, 0, "-7.5-math.sin(q.anim_time*90*1-90)*1"]
},
"neck_fur_right2": {
"rotation": [0, 0, "7.5+math.sin(q.anim_time*90*1-90)*1"]
},
"neck2": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1-90)*0.5", 0, 0]
},
"head_rotation": {
"rotation": ["32.5+math.sin(q.anim_time*90*1-90)*-2", 0, "0-math.sin(q.anim_time*90*1-120)*-0.5"]
},
"hair2": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-210)*1", 0, 0]
},
"hair_back_top": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-300)*2", 0, 0]
},
"hair_back_top2": {
"rotation": ["-22.5+math.sin(q.anim_time*90*1-360)*4", 0, 0]
},
"hair_back_bottom2": {
"rotation": ["-20+math.sin(q.anim_time*90*1-380)*4", 0, 0]
},
"tail_middle": {
"rotation": ["42.5+math.sin(q.anim_time*90*1-60)*-0.5", 0, 0]
},
"tail_middle2": {
"rotation": ["7.5+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
},
"tail_middle3": {
"rotation": ["17.5+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_middle4": {
"rotation": ["-37.5+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_middle5": {
"rotation": ["-35+math.sin(q.anim_time*90*1-300)*-6", 2.5, 0]
},
"tail_middle6": {
"rotation": ["-42.5+math.sin(q.anim_time*90*1-300)*-6", 0, 0]
},
"tail_middle7": {
"rotation": ["-25+math.sin(q.anim_time*90*1-400)*-6", 0, 0]
},
"tail_middle8": {
"rotation": ["35+math.sin(q.anim_time*90*1-460)*-12", 0, 0]
},
"tail_left1_rotation": {
"rotation": ["27.525638448+math.sin(q.anim_time*90*1-60)*-0.5", 2.04767, 1.43455]
},
"tail_left1_2": {
"rotation": ["15.013645339+math.sin(q.anim_time*90*1-120)*-1", 2.41476, 0.64743]
},
"tail_left1_3": {
"rotation": ["17.5+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_left1_4": {
"rotation": ["-32.599068173+math.sin(q.anim_time*90*1-240)*-4", -4.21541, 2.69136]
},
"tail_left1_5": {
"rotation": ["-37.605552+math.sin(q.anim_time*90*1-300)*-6", -3.9649, 3.04868]
},
"tail_left1_6": {
"rotation": ["-40.107597848+math.sin(q.anim_time*90*1-360)*-4", 3.82821, -3.21873]
},
"tail_left1_7": {
"rotation": ["-27.702122918+math.sin(q.anim_time*90*1-400)*-6", 6.64851, -3.47875]
},
"tail_left1_8": {
"rotation": ["30.867477791+math.sin(q.anim_time*90*1-460)*-12", 12.95254, 7.63074]
},
"tail_left2_rotation": {
"rotation": ["22.577335588+math.sin(q.anim_time*90*1-60)*-0.5", 4.61854, 1.91757]
},
"tail_left2_2": {
"rotation": ["12.5+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
},
"tail_left2_3": {
"rotation": ["15+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_left2_4": {
"rotation": ["-20+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_left2_5": {
"rotation": ["-56.265008831+math.sin(q.anim_time*90*1-300)*-6", -9.93191, 14.48174]
},
"tail_left2_6": {
"rotation": ["-37.158458405+math.sin(q.anim_time*90*1-300)*-6", 18.26883, -13.36473]
},
"tail_left2_7": {
"rotation": ["33.125975871+math.sin(q.anim_time*90*1-360)*-12", 10.51794, 6.79286]
},
"tail_left3_rotation": {
"rotation": ["10+math.sin(q.anim_time*90*1-60)*-0.5", 0, 0]
},
"tail_left3_2": {
"rotation": ["22.577335588+math.sin(q.anim_time*90*1-120)*-1", 4.61854, 1.91757]
},
"tail_left3_3": {
"rotation": ["10+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_left3_4": {
"rotation": ["-30+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_left3_5": {
"rotation": ["-27.860824367+math.sin(q.anim_time*90*1-300)*-6", -8.86042, 4.65468]
},
"tail_left3_6": {
"rotation": ["-43.1852829+math.sin(q.anim_time*90*1-300)*-6", 9.18229, -8.51814]
},
"tail_left3_7": {
"rotation": ["35.413183453+math.sin(q.anim_time*90*1-360)*-12", 8.17773, 5.77509]
},
"tail_right1_rotation": {
"rotation": ["27.525638448+math.sin(q.anim_time*90*1-60)*-0.5", -2.04767, -1.43455]
},
"tail_right1_2": {
"rotation": ["15.013645339+math.sin(q.anim_time*90*1-120)*-1", -2.41476, -0.64743]
},
"tail_right1_3": {
"rotation": ["17.5+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_right1_4": {
"rotation": ["-32.599068173+math.sin(q.anim_time*90*1-240)*-4", 4.21541, -2.69136]
},
"tail_right1_5": {
"rotation": ["-37.605552+math.sin(q.anim_time*90*1-300)*-6", 3.9649, -3.04868]
},
"tail_right1_6": {
"rotation": ["-40.107597848+math.sin(q.anim_time*90*1-360)*-4", -3.82821, 3.21873]
},
"tail_right1_7": {
"rotation": ["-27.702122918+math.sin(q.anim_time*90*1-400)*-6", -6.64851, 3.47875]
},
"tail_right1_8": {
"rotation": ["30.867477791+math.sin(q.anim_time*90*1-460)*-12", -12.95254, -7.63074]
},
"tail_right2_rotation": {
"rotation": ["22.577335588+math.sin(q.anim_time*90*1-60)*-0.5", -4.61854, -1.91757]
},
"tail_right2_2": {
"rotation": ["12.5+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
},
"tail_right2_3": {
"rotation": ["15+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_right2_4": {
"rotation": ["-20+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_right2_5": {
"rotation": ["-56.265008831+math.sin(q.anim_time*90*1-300)*-6", 9.93191, -14.48174]
},
"tail_right2_6": {
"rotation": ["-37.158458405+math.sin(q.anim_time*90*1-300)*-6", -18.26883, 13.36473]
},
"tail_right2_7": {
"rotation": ["33.125975871+math.sin(q.anim_time*90*1-360)*-12", -10.51794, -6.79286]
},
"leg_front_left": {
"rotation": ["-9.981069394+math.sin(q.anim_time*90*1-0)*-1", 0.43523, 4.98107],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.025", "0-math.sin(q.anim_time*90*1-0)*-0.15"]
},
"leg_front_left2": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-0)*0.5", 0, 0]
},
"foot_front_left": {
"rotation": ["12.5+math.sin(q.anim_time*90*1-0)*0.5", 0, -5]
},
"leg_back_left": {
"rotation": ["10+math.sin(q.anim_time*90*1-0)*1", 0, -7.5],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.2", "0-math.sin(q.anim_time*90*1-0)*0.25"]
},
"leg_back_left2": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-0)*1", 0, 0]
},
"leg_back_left3": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-0)*-1", 0, 0]
},
"foot_back_left": {
"rotation": ["-5+math.sin(q.anim_time*90*1-0)*-1", 0, 7.5]
},
"leg_front_right": {
"rotation": ["10.018930606+math.sin(q.anim_time*90*1-0)*-1", -0.43523, -4.98107],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.025", "0-math.sin(q.anim_time*90*1-0)*-0.15"]
},
"leg_front_right2": {
"rotation": ["-10+math.sin(q.anim_time*90*1-0)*0.5", 0, 0]
},
"foot_front_right": {
"rotation": ["-0+math.sin(q.anim_time*90*1-0)*0.5", 0, 5]
},
"leg_back_right": {
"rotation": ["17.521361057+math.sin(q.anim_time*90*1-0)*1", 0.32621, 7.49294],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.2", "0-math.sin(q.anim_time*90*1-0)*0.25"]
},
"leg_back_right2": {
"rotation": ["-5+math.sin(q.anim_time*90*1-0)*1", 0, 0]
},
"leg_back_right3": {
"rotation": ["2.5+math.sin(q.anim_time*90*1-0)*-1", 0, 0]
},
"foot_back_right": {
"rotation": ["-15+math.sin(q.anim_time*90*1-0)*-1", 0, -7.5]
},
"tail_right3_rotation": {
"rotation": ["10+math.sin(q.anim_time*90*1-60)*-0.5", 0, 0]
},
"tail_right3_2": {
"rotation": ["22.577335588+math.sin(q.anim_time*90*1-120)*-1", -4.61854, -1.91757]
},
"tail_right3_3": {
"rotation": ["10+math.sin(q.anim_time*90*1-180)*-1", 0, 0]
},
"tail_right3_4": {
"rotation": ["-30+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_right3_5": {
"rotation": ["-27.860824367+math.sin(q.anim_time*90*1-300)*-6", 8.86042, -4.65468]
},
"tail_right3_6": {
"rotation": ["-43.1852829+math.sin(q.anim_time*90*1-300)*-6", -9.18229, 8.51814]
},
"tail_right3_7": {
"rotation": ["35.413183453+math.sin(q.anim_time*90*1-360)*-12", -8.17773, -5.77509]
},
"tail_left4_rotation": {
"rotation": ["-0+math.sin(q.anim_time*90*1-60)*-0.5", 10, 0]
},
"tail_left4_2": {
"rotation": ["17.5+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
},
"tail_left4_3": {
"rotation": ["20.4458201+math.sin(q.anim_time*90*1-180)*-2", -11.73507, -4.3361]
},
"tail_left4_4": {
"rotation": ["-41.341977449+math.sin(q.anim_time*90*1-240)*-4", -13.31791, 11.45696]
},
"tail_left4_5": {
"rotation": ["-35.413183453+math.sin(q.anim_time*90*1-300)*-6", 8.17773, -5.77509]
},
"tail_left4_6": {
"rotation": ["39.711284319+math.sin(q.anim_time*90*1-360)*-12", 17.67415, 14.15251]
},
"tail_right4_rotation": {
"rotation": ["-0+math.sin(q.anim_time*90*1-60)*-0.5", -10, 0]
},
"tail_right4_2": {
"rotation": ["17.5+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
},
"tail_right4_3": {
"rotation": ["20.4458201+math.sin(q.anim_time*90*1-180)*-2", 11.73507, 4.3361]
},
"tail_right4_4": {
"rotation": ["-41.341977449+math.sin(q.anim_time*90*1-240)*-4", 13.31791, -11.45696]
},
"tail_right4_5": {
"rotation": ["-35.413183453+math.sin(q.anim_time*90*1-300)*-6", -8.17773, 5.77509]
},
"tail_right4_6": {
"rotation": ["39.711284319+math.sin(q.anim_time*90*1-360)*-12", -17.67415, -14.15251]
},
"neck_fur_front": {
"rotation": ["-0+math.sin(q.anim_time*90*1-60)*-1", 0, 0]
},
"neck_fur_front2": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*2", 0, 0]
},
"neck_fur_front3": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*2", 0, 0]
},
"ear_left": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*1", 0, "0-math.sin(q.anim_time*90*1-30)*2"]
},
"ear_right": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*1", 0, "-0+math.sin(q.anim_time*90*1-30)*2"]
},
"hair": {
"rotation": ["-0+math.sin(q.anim_time*90*1-150)*2", 0, 0]
},
"hair_detail": {
"rotation": ["-0+math.sin(q.anim_time*90*1-180)*1", 0, 0]
},
"hair_detail2": {
"rotation": ["-0+math.sin(q.anim_time*90*1-240)*1", 0, 0]
},
"hair_back_bottom": {
"rotation": ["-0+math.sin(q.anim_time*90*1-320)*2", 0, 0]
}
}
},
"animation.ninetales.base": {
"loop": true,
"bones": {
"body": {
@@ -276,64 +582,6 @@
}
}
},
"animation.ninetales.cry": {
"animation_length": 1,
"bones": {
"mouth": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -0.0999, -0.00436],
"0.75": [0, -0.0999, -0.00436],
"1.0": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [65, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [65, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.ninetales.cry"
}
}
},
"animation.ninetales.blink": {
"animation_length": 0.1667,
"bones": {
@@ -413,6 +661,164 @@
"position": [-0.1, 0, -0.1]
}
}
},
"animation.ninetales.cry": {
"animation_length": 2,
"bones": {
"torso": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-2, 0, 0],
"lerp_mode": "catmullrom"
},
"1.3333": {
"post": [-4, 0, 0],
"lerp_mode": "catmullrom"
},
"1.6667": {
"post": [-0.5, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"neck2": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head_rotation": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [-22.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-27, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"1.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"1.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"jaw": {
"rotation": {
"0.2917": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [47.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [20, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5417": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": [0, 0, 0]
},
"hair": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.1667": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.3333": {
"effect": "pokemon.ninetales.cry"
}
}
}
}
}
@@ -1,7 +1,7 @@
{
"format_version": "1.8.0",
"animations": {
"animation.ninetales_alolan.ground_idle": {
"animation.ninetales_alolan.base": {
"loop": true,
"bones": {
"body": {
@@ -381,61 +381,411 @@
}
}
},
"animation.ninetales_alolan.cry": {
"animation_length": 1,
"animation.ninetales_alolan.ground_idle": {
"loop": true,
"bones": {
"mouth": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -0.0999, -0.00436],
"0.75": [0, -0.0999, -0.00436],
"1.0": [0, 0, 0]
}
"body": {
"position": [0, -0.25, 0]
},
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
"torso": {
"rotation": ["2.5+math.sin(q.anim_time*90*1-0)*0.5", 0, "0-math.sin(q.anim_time*90*0.5-30)*0.5"]
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [65, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [65, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.ninetales_alolan.cry"
"chest": {
"rotation": ["-5+math.sin(q.anim_time*90*1-30)*0.5", 0, 0]
},
"neck": {
"rotation": ["-10+math.sin(q.anim_time*90*1-60)*1", 0, 0]
},
"neck2": {
"rotation": ["-10+math.sin(q.anim_time*90*1-90)*0.5", 0, 0]
},
"head_rotation": {
"rotation": ["14.54701+math.sin(q.anim_time*90*1-90)*-2", -3.59452, "0.40543-math.sin(q.anim_time*90*1-120)*-0.5"]
},
"hair": {
"rotation": ["13.75153+math.sin(q.anim_time*90*1-90)*1", 7.26228, 1.47729]
},
"hair2": {
"rotation": ["-12.54624+math.sin(q.anim_time*90*1-120)*2", 4.88119, -1.08482]
},
"hair3": {
"rotation": ["-24.58726+math.sin(q.anim_time*90*1-180)*2", -15.69466, 1.78427]
},
"hair4": {
"rotation": ["3.48303+math.sin(q.anim_time*90*1-240)*4", -24.77164, -8.26511]
},
"hair5": {
"rotation": ["-7.97337+math.sin(q.anim_time*90*1-300)*8", -59.03741, 4.53051]
},
"hair_bottom": {
"rotation": ["7.5+math.sin(q.anim_time*90*1-360)*12", 0, 0]
},
"hair_bottom2": {
"rotation": ["-27.70212+math.sin(q.anim_time*90*1-420)*18", -6.64851, 3.47875]
},
"hair_bottom3": {
"rotation": ["25.56145+math.sin(q.anim_time*90*1-480)*24", -27.51235, -12.45891]
},
"hair6": {
"rotation": ["7.5+math.sin(q.anim_time*90*1-360)*12", 0, 0]
},
"hair7": {
"rotation": ["-40.98084+math.sin(q.anim_time*90*1-420)*18", -11.43563, 9.77243]
},
"hair8": {
"rotation": ["30.86748+math.sin(q.anim_time*90*1-480)*24", -12.95254, -7.63074]
},
"tail": {
"rotation": [0, 0, 0]
},
"tail_middle_rotation": {
"rotation": ["65+math.sin(q.anim_time*90*1-60)*-0.5", 0, 0]
},
"tail_middle2": {
"rotation": ["-7.5+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
},
"tail_middle3": {
"rotation": ["-25+math.sin(q.anim_time*90*1-180)*-2", 0, 0]
},
"tail_middle4": {
"rotation": ["-30+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_middle5": {
"rotation": ["-25+math.sin(q.anim_time*90*1-300)*-6", 0, 0]
},
"tail_middle6": {
"rotation": ["-12.62353+math.sin(q.anim_time*90*1-360)*-12", 7.24305, -1.95155]
},
"tail_middle7": {
"rotation": ["-31.18939+math.sin(q.anim_time*90*1-400)*-12", -15.09492, 8.95891]
},
"tail_middle8": {
"rotation": ["15.22074+math.sin(q.anim_time*90*1-460)*-12", 9.65594, 2.61298]
},
"tail_middle9": {
"rotation": ["-20+math.sin(q.anim_time*90*1-520)*-18", 0, 0]
},
"tail_left1_rotation": {
"rotation": ["64.2174+math.sin(q.anim_time*90*1-60)*-0.5", 8.98581, 12.04686]
},
"tail_left1_2": {
"rotation": ["-17.51565+math.sin(q.anim_time*90*1-120)*-1", -2.38422, 0.7522]
},
"tail_left1_3": {
"rotation": ["-10.03742+math.sin(q.anim_time*90*1-180)*-2", -4.92385, 0.87038]
},
"tail_left1_4": {
"rotation": ["-37.52635+math.sin(q.anim_time*90*1-240)*-4", -1.98315, 1.52251]
},
"tail_left1_5": {
"rotation": ["-17.51565+math.sin(q.anim_time*90*1-300)*-6", -2.38422, 0.7522]
},
"tail_left1_6": {
"rotation": ["-25.08377+math.sin(q.anim_time*90*1-360)*-12", -4.53051, 2.11751]
},
"tail_left1_7": {
"rotation": ["-15.22074+math.sin(q.anim_time*90*1-400)*-12", 9.65594, -2.61298]
},
"tail_left1_8": {
"rotation": ["30.71983+math.sin(q.anim_time*90*1-460)*-12", -13.97399, -3.85625]
},
"tail_left1_9": {
"rotation": ["-42.24682+math.sin(q.anim_time*90*1-520)*-18", 17.04679, -14.9092]
},
"tail_left2_rotation": {
"rotation": ["63.58314+math.sin(q.anim_time*90*1-60)*-0.5", 11.98346, 41.65117]
},
"tail_left2_2": {
"rotation": ["-15.50409+math.sin(q.anim_time*90*1-120)*-1", -14.47751, 3.96713]
},
"tail_left2_3": {
"rotation": ["-9.9045+math.sin(q.anim_time*90*1-180)*-2", -2.61747, -1.08202]
},
"tail_left2_4": {
"rotation": ["-27.5209+math.sin(q.anim_time*90*1-240)*-4", -2.26564, 1.0571]
},
"tail_left2_5": {
"rotation": ["-30.09468+math.sin(q.anim_time*90*1-300)*-6", -4.32875, 2.50477]
},
"tail_left2_6": {
"rotation": ["-13.06681+math.sin(q.anim_time*90*1-360)*-12", 11.06861, -5.84485]
},
"tail_left2_7": {
"rotation": ["-25.08377+math.sin(q.anim_time*90*1-400)*-12", 4.53051, -2.11751]
},
"tail_left2_8": {
"rotation": ["21.88023+math.sin(q.anim_time*90*1-460)*-12", -23.39896, -9.06159]
},
"tail_left2_9": {
"rotation": ["-0+math.sin(q.anim_time*90*1-520)*-18", 25, 0]
},
"tail_left3": {
"rotation": [-7.34619, 17.12827, -7.84022]
},
"tail_left3_rotation": {
"rotation": ["76.5201+math.sin(q.anim_time*90*1-60)*-0.5", -21.21599, 70.91151]
},
"tail_left3_2": {
"rotation": ["-23.00013+math.sin(q.anim_time*90*1-120)*-1", -11.40209, 5.14995]
},
"tail_left3_3": {
"rotation": ["-10+math.sin(q.anim_time*90*1-180)*-2", 0, 0]
},
"tail_left3_4": {
"rotation": ["-20+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_left3_5": {
"rotation": ["-30.02363+math.sin(q.anim_time*90*1-300)*-6", 2.16489, -1.2506]
},
"tail_left3_6": {
"rotation": ["-12.99008+math.sin(q.anim_time*90*1-360)*-12", 11.53486, -4.8493]
},
"tail_left3_7": {
"rotation": ["15+math.sin(q.anim_time*90*1-400)*-12", 20, 0]
},
"tail_left3_8": {
"rotation": ["-22.89875+math.sin(q.anim_time*90*1-460)*-12", -8.42145, 5.41207]
},
"tail_left3_9": {
"rotation": ["30+math.sin(q.anim_time*90*1-520)*-18", 22.5, 0]
},
"tail_left4_rotation": {
"rotation": ["83.07626+math.sin(q.anim_time*90*1-60)*-0.5", 7.16729, 88.89799]
},
"tail_left4_2": {
"rotation": ["-28.3693+math.sin(q.anim_time*90*1-120)*-1", -12.72029, 8.00075]
},
"tail_left4_3": {
"rotation": ["-12.60443+math.sin(q.anim_time*90*1-180)*-2", -7.32123, 1.63219]
},
"tail_left4_4": {
"rotation": ["-15.04624+math.sin(q.anim_time*90*1-240)*-4", -4.88119, 1.08482]
},
"tail_left4_5": {
"rotation": ["-29.41237+math.sin(q.anim_time*90*1-300)*-6", -2.14804, -1.84068]
},
"tail_left4_6": {
"rotation": ["-9.14867+math.sin(q.anim_time*90*1-360)*-12", 20.70481, -9.00717]
},
"tail_left4_7": {
"rotation": ["-15+math.sin(q.anim_time*90*1-400)*-12", -2.5, 0]
},
"tail_left4_8": {
"rotation": ["10+math.sin(q.anim_time*90*1-460)*-12", 20, 0]
},
"tail_left4_9": {
"rotation": ["-0+math.sin(q.anim_time*90*1-520)*-18", -25, 0]
},
"tail_right1_rotation": {
"rotation": ["64.2174+math.sin(q.anim_time*90*1-60)*-0.5", -8.98581, -12.04686]
},
"tail_right1_2": {
"rotation": ["-17.51565+math.sin(q.anim_time*90*1-120)*-1", 2.38422, -0.7522]
},
"tail_right1_3": {
"rotation": ["-10.03742+math.sin(q.anim_time*90*1-180)*-2", 4.92385, -0.87038]
},
"tail_right1_4": {
"rotation": ["-37.52635+math.sin(q.anim_time*90*1-240)*-4", 1.98315, -1.52251]
},
"tail_right1_5": {
"rotation": ["-17.51565+math.sin(q.anim_time*90*1-300)*-6", 2.38422, -0.7522]
},
"tail_right1_6": {
"rotation": ["-25.08377+math.sin(q.anim_time*90*1-360)*-12", 4.53051, -2.11751]
},
"tail_right1_7": {
"rotation": ["-15.22074+math.sin(q.anim_time*90*1-400)*-12", -9.65594, 2.61298]
},
"tail_right1_8": {
"rotation": ["30.71983+math.sin(q.anim_time*90*1-460)*-12", 13.97399, 3.85625]
},
"tail_right1_9": {
"rotation": ["-42.24682+math.sin(q.anim_time*90*1-520)*-18", -17.04679, 14.9092]
},
"tail_right2_rotation": {
"rotation": ["63.58314+math.sin(q.anim_time*90*1-60)*-0.5", -11.98346, -41.65117]
},
"tail_right2_2": {
"rotation": ["-15.50409+math.sin(q.anim_time*90*1-60)*-0.5", 14.47751, -3.96713]
},
"tail_right2_3": {
"rotation": ["-9.9045+math.sin(q.anim_time*90*1-180)*-2", 2.61747, 1.08202]
},
"tail_right2_4": {
"rotation": ["-27.5209+math.sin(q.anim_time*90*1-240)*-4", 2.26564, -1.0571]
},
"tail_right2_5": {
"rotation": ["-30.09468+math.sin(q.anim_time*90*1-300)*-6", 4.32875, -2.50477]
},
"tail_right2_6": {
"rotation": ["-13.06681+math.sin(q.anim_time*90*1-360)*-12", -11.06861, 5.84485]
},
"tail_right2_7": {
"rotation": ["-25.08377+math.sin(q.anim_time*90*1-400)*-12", -4.53051, 2.11751]
},
"tail_right2_8": {
"rotation": ["21.88023+math.sin(q.anim_time*90*1-460)*-12", 23.39896, 9.06159]
},
"tail_right2_9": {
"rotation": ["-0+math.sin(q.anim_time*90*1-520)*-18", -25, 0]
},
"leg_front_left": {
"rotation": ["-4.99527+math.sin(q.anim_time*90*1-0)*-1", 0.21782, 2.4905],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.025", "0-math.sin(q.anim_time*90*1-0)*-0.15"]
},
"leg_front_left2": {
"rotation": ["-5+math.sin(q.anim_time*90*1-0)*0.5", 0, 0]
},
"foot_front_left": {
"rotation": ["9.99067+math.sin(q.anim_time*90*1-0)*0.5", 0.43399, -2.46207]
},
"leg_back_left": {
"rotation": ["12.5048+math.sin(q.anim_time*90*1-0)*1", 1.93726, -2.22807],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.2", "0-math.sin(q.anim_time*90*1-0)*0.25"]
},
"leg_back_left2": {
"rotation": ["-5+math.sin(q.anim_time*90*1-0)*1", 0, 0]
},
"leg_back_left3": {
"rotation": ["-2.49673+math.sin(q.anim_time*90*1-0)*-1", -0.12261, 0.03929]
},
"foot_back_left": {
"rotation": ["-5.00899+math.sin(q.anim_time*90*1-0)*-1", -0.3507, 2.5603]
},
"leg_front_right": {
"rotation": ["7.47178+math.sin(q.anim_time*90*1-0)*-1", 0.65182, -4.95744],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.025", "0-math.sin(q.anim_time*90*1-0)*-0.15"]
},
"leg_front_right2": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-0)*0.5", 0, 0]
},
"foot_front_right": {
"rotation": ["-5+math.sin(q.anim_time*90*1-0)*0.5", 0, 5]
},
"leg_back_right": {
"rotation": ["-9.8369+math.sin(q.anim_time*90*1-0)*1", 5.47408, 1.12804],
"position": [0, "0-math.sin(q.anim_time*90*1-0)*0.2", "0-math.sin(q.anim_time*90*1-0)*0.25"]
},
"leg_back_right2": {
"rotation": ["5+math.sin(q.anim_time*90*1-0)*1", 0, 0]
},
"leg_back_right3": {
"rotation": ["-0+math.sin(q.anim_time*90*1-0)*-1", 0, 0]
},
"foot_back_right": {
"rotation": ["4.98247+math.sin(q.anim_time*90*1-0)*-1", 0.85481, -2.34941]
},
"tail_right3": {
"rotation": [-7.34619, -17.12827, 7.84022]
},
"tail_right3_rotation": {
"rotation": ["76.5201+math.sin(q.anim_time*90*1-60)*-0.5", 21.21599, -70.91151]
},
"tail_right3_2": {
"rotation": ["-23.00013+math.sin(q.anim_time*90*1-120)*-1", 11.40209, -5.14995]
},
"tail_right3_3": {
"rotation": ["-10+math.sin(q.anim_time*90*1-180)*-2", 0, 0]
},
"tail_right3_4": {
"rotation": ["-20+math.sin(q.anim_time*90*1-240)*-4", 0, 0]
},
"tail_right3_5": {
"rotation": ["-30.02363+math.sin(q.anim_time*90*1-300)*-6", -2.16489, 1.2506]
},
"tail_right3_6": {
"rotation": ["-12.99008+math.sin(q.anim_time*90*1-360)*-12", -11.53486, 4.8493]
},
"tail_right3_7": {
"rotation": ["15+math.sin(q.anim_time*90*1-400)*-12", -20, 0]
},
"tail_right3_8": {
"rotation": ["-22.89875+math.sin(q.anim_time*90*1-460)*-12", 8.42145, -5.41207]
},
"tail_right3_9": {
"rotation": ["30+math.sin(q.anim_time*90*1-520)*-18", -22.5, 0]
},
"tail_right4_rotation": {
"rotation": ["83.07626+math.sin(q.anim_time*90*1-60)*-0.5", -7.16729, -88.89799]
},
"tail_right4_2": {
"rotation": ["-28.3693+math.sin(q.anim_time*90*1-120)*-1", 12.72029, -8.00075]
},
"tail_right4_3": {
"rotation": ["-12.60443+math.sin(q.anim_time*90*1-180)*-2", 7.32123, -1.63219]
},
"tail_right4_4": {
"rotation": ["-15.04624+math.sin(q.anim_time*90*1-240)*-4", 4.88119, -1.08482]
},
"tail_right4_5": {
"rotation": ["-29.41237+math.sin(q.anim_time*90*1-300)*-6", 2.14804, 1.84068]
},
"tail_right4_6": {
"rotation": ["-9.14867+math.sin(q.anim_time*90*1-360)*-12", -20.70481, 9.00717]
},
"tail_right4_7": {
"rotation": ["-15+math.sin(q.anim_time*90*1-400)*-12", 2.5, 0]
},
"tail_right4_8": {
"rotation": ["10+math.sin(q.anim_time*90*1-460)*-12", -20, 0]
},
"tail_right4_9": {
"rotation": ["-0+math.sin(q.anim_time*90*1-520)*-18", 25, 0]
},
"hair_left": {
"rotation": [0, -17.5, "55+math.sin(q.anim_time*90*1-120)*2"]
},
"hair_left2": {
"rotation": [-1.6575, 12.39135, "9.82005+math.sin(q.anim_time*90*1-180)*4"]
},
"hair_left3": {
"rotation": [8.00384, 21.21629, "20.75164+math.sin(q.anim_time*90*1-240)*8"]
},
"hair_left4": {
"rotation": [7.90373, -21.34916, "-15.85201+math.sin(q.anim_time*90*1-300)*18"]
},
"hair_left5": {
"rotation": [-6.42784, -34.18333, "7.10385+math.sin(q.anim_time*90*1-360)*24"]
},
"hair_right": {
"rotation": [0, 17.5, "-55-math.sin(q.anim_time*90*1-120)*2"]
},
"hair_right2": {
"rotation": [-1.6575, -12.39135, "-9.82005-math.sin(q.anim_time*90*1-180)*4"]
},
"hair_right3": {
"rotation": [8.00384, -21.21629, "-20.75164-math.sin(q.anim_time*90*1-240)*8"]
},
"hair_right4": {
"rotation": [7.90373, 21.34916, "15.85201-math.sin(q.anim_time*90*1-300)*18"]
},
"hair_right5": {
"rotation": [-6.42784, 34.18333, "-7.10385-math.sin(q.anim_time*90*1-360)*24"]
},
"neck_fur_front": {
"rotation": ["-0+math.sin(q.anim_time*90*1-60)*-1", 0, 0]
},
"neck_fur_front2": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*2", 0, 0]
},
"neck_fur_front3": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*2", 0, 0]
},
"neck_fur_left": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-90)*1"]
},
"neck_fur_right": {
"rotation": [0, 0, "-0+math.sin(q.anim_time*90*1-90)*1"]
},
"ear_left": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*1", 0, "0-math.sin(q.anim_time*90*1-30)*2"]
},
"ear_right": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*1", 0, "-0+math.sin(q.anim_time*90*1-30)*2"]
},
"hair_front": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*2", 0, 0]
}
}
},
@@ -518,6 +868,176 @@
"position": [-0.1, 0, -0.1]
}
}
},
"animation.ninetales_alolan.cry": {
"animation_length": 2,
"bones": {
"torso": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-2, 0, 0],
"lerp_mode": "catmullrom"
},
"1.3333": {
"post": [-4, 0, 0],
"lerp_mode": "catmullrom"
},
"1.6667": {
"post": [-0.5, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"neck2": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head_rotation": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [-22.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-27, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"1.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"1.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"jaw": {
"rotation": {
"0.2917": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [47.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [20, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5417": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": [0, 0, 0]
},
"hair": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.1667": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.3333": {
"effect": "pokemon.ninetales_alolan.cry"
}
}
}
}
}
@@ -3,58 +3,274 @@
"animations": {
"animation.mudkip.ground_idle": {
"loop": true,
"animation_length": 2,
"bones": {
"head": {
"rotation": [2.5, 0, 0]
"rotation": ["2.5+math.sin(q.anim_time*90*4-90)*1.5", "math.sin(q.anim_time*90*2-60)*1.5", "math.sin(q.anim_time*90*2-60)*1"]
},
"fin2": {
"rotation": [2.5, 0, 0]
"rotation": [2.5, 0, "0+math.sin(q.anim_time*90*2-150)*-3"]
},
"cheek_left2": {
"rotation": [0, -7.5, 0]
"rotation": [0, -7.5, "0+math.sin(q.anim_time*90*4-90)*1.5"]
},
"leg_front_left": {
"rotation": [7.5, 5, 0]
"rotation": ["5+math.sin(q.anim_time*90*4)*2", 5, 0],
"position": [0, "-0.125+math.sin(q.anim_time*90*4)*-0.05", "0+math.sin(q.anim_time*90*4)*-0.07"]
},
"leg_front_left2": {
"rotation": [-7.5, 0, 0]
"rotation": ["-5+math.sin(q.anim_time*90*4)*-2", 0, 0]
},
"leg_front_right": {
"rotation": [7.5, -5, 0]
"rotation": ["5+math.sin(q.anim_time*90*4)*2", -5, 0],
"position": [0, "-0.125+math.sin(q.anim_time*90*4)*-0.05", "0+math.sin(q.anim_time*90*4)*-0.07"]
},
"leg_front_right2": {
"rotation": [-7.5, 0, 0]
"rotation": ["-5+math.sin(q.anim_time*90*4)*-2", 0, 0]
},
"leg_back_left": {
"rotation": [5, -5, 0]
"rotation": ["-5+math.sin(q.anim_time*90*4)*-1", -5, 0],
"position": [0, "-0.125+math.sin(q.anim_time*90*4)*-0.025", "0+math.sin(q.anim_time*90*4)*0.035"]
},
"leg_back_left2": {
"rotation": [-5, 0, 0]
"rotation": ["5+math.sin(q.anim_time*90*4)*1", 0, 0]
},
"leg_back_right": {
"rotation": [5, 5, 0]
"rotation": ["-5+math.sin(q.anim_time*90*4)*-1", 5, 0],
"position": [0, "-0.125+math.sin(q.anim_time*90*4)*-0.025", "0+math.sin(q.anim_time*90*4)*0.035"]
},
"leg_back_right2": {
"rotation": [-5, 0, 0]
"rotation": ["5+math.sin(q.anim_time*90*4)*1", 0, 0]
},
"body": {
"position": [0, -0.1, 0]
},
"tail": {
"rotation": [5, 0, 0]
"rotation": ["6+math.sin(q.anim_time*90*4)*1", "0+math.sin(q.anim_time*90*2-90)*-10", 0]
},
"fin": {
"rotation": [2.5, 0, 0]
"rotation": [2.5, 0, "0+math.sin(q.anim_time*90*2-90)*-4"]
},
"cheek_right2": {
"rotation": [0, -7.5, 0]
"rotation": [0, 7.5, "0+math.sin(q.anim_time*90*4-90)*-1.5"]
},
"torso": {
"rotation": ["0+math.sin(q.anim_time*90*4)*0.75", "0+math.sin(q.anim_time*90*2-30)*0.5", 0],
"position": [0, "0+math.sin(q.anim_time*90*4+30)*-0.05", 0]
},
"tail2": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-150)*-12.5", 0]
}
}
},
"animation.mudkip.battle_idle": {
"loop": true,
"animation_length": 2,
"bones": {
"head": {
"rotation": ["-7.5+math.sin(q.anim_time*90*4-90)*3", "math.sin(q.anim_time*90*2-60)*1", "math.sin(q.anim_time*90*2-60)*1"]
},
"fin2": {
"rotation": [2.5, 0, "0+math.sin(q.anim_time*90*2-120)*-3"]
},
"cheek_left2": {
"rotation": [0, -7.5, "-5+math.sin(q.anim_time*90*4-90)*1.5"]
},
"leg_front_left": {
"rotation": ["4.305+math.sin(q.anim_time*90*4)*2", 5.60922, -7.50745],
"position": [0, "-0.275+math.sin(q.anim_time*90*4)*-0.05", "0.3+math.sin(q.anim_time*90*4)*-0.07"]
},
"leg_front_left2": {
"rotation": ["-4.9575+math.sin(q.anim_time*90*4)*-2", 0.65182, 7.47178]
},
"leg_front_right": {
"rotation": ["4.305+math.sin(q.anim_time*90*4)*2", -5.60922, 7.50745],
"position": [0, "-0.275+math.sin(q.anim_time*90*4)*-0.05", "0.3+math.sin(q.anim_time*90*4)*-0.07"]
},
"leg_front_right2": {
"rotation": ["-4.9575+math.sin(q.anim_time*90*4)*-2", -0.65182, -7.47178]
},
"leg_back_left": {
"rotation": ["-5+math.sin(q.anim_time*90*4)*-1", -5, 0],
"position": [0, "-0.125+math.sin(q.anim_time*90*4)*-0.025", "0+math.sin(q.anim_time*90*4)*0.035"]
},
"leg_back_left2": {
"rotation": ["5+math.sin(q.anim_time*90*4)*1", 0, 0]
},
"leg_back_right": {
"rotation": ["-5+math.sin(q.anim_time*90*4)*-1", 5, 0],
"position": [0, "-0.125+math.sin(q.anim_time*90*4)*-0.025", "0+math.sin(q.anim_time*90*4)*0.035"]
},
"leg_back_right2": {
"rotation": ["5+math.sin(q.anim_time*90*4)*1", 0, 0]
},
"body": {
"position": [0, -0.1, 0]
},
"tail": {
"rotation": ["6+math.sin(q.anim_time*90*4)*1", "0+math.sin(q.anim_time*90*2-90)*-17.5", 0]
},
"fin": {
"rotation": [2.5, 0, "0+math.sin(q.anim_time*90*2-90)*-4"]
},
"cheek_right2": {
"rotation": [0, 7.5, "5+math.sin(q.anim_time*90*4-90)*-1.5"]
},
"torso": {
"rotation": ["10+math.sin(q.anim_time*90*4)*2.5", "math.sin(q.anim_time*90*2-30)*0.5", 0],
"position": [0, "0+math.sin(q.anim_time*90*4+30)*-0.07", 0]
},
"tail2": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-90)*-7.5", 0]
},
"eye_angry_left": {
"position": [0, 0, -0.1]
},
"eye_angry_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.mudkip.cry": {
"animation_length": 1.2,
"animation_length": 1.75,
"bones": {
"torso": {
"rotation": {
"0.0": [0, 0, 0],
"0.2917": [5, 0, 0],
"0.5": [0, 0, 0],
"1.0": [-2.5, 0, 0],
"1.5": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [-10, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [-10, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [-17.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.2917": {
"post": [-3, 0, 0],
"lerp_mode": "catmullrom"
},
"1.625": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [35, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [15, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [60, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [60, 0, 0],
"lerp_mode": "catmullrom"
},
"1.3333": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"fin": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [6, 0, 0],
"1.0": [-5, 0, 0],
"1.5": [0, 0, 0]
}
},
"cheek_left2": {
"rotation": {
"0.375": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 0, -12.5],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [0, 0, -12.5],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"cheek_right2": {
"rotation": {
"0.375": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 0, 12.5],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [0, 0, 12.5],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"tail": {
"rotation": {
"0.0": [0, 0, 0],
"0.625": [0, "0+math.sin(q.anim_time*90*12-90)*-25", 0],
"1.625": [0, 0, 0]
}
}
},
"sound_effects": {
"0.04": {
"0.5417": {
"effect": "pokemon.mudkip.cry"
}
}
@@ -207,6 +423,14 @@
"position": [-0.1, 0, -0.1]
}
}
},
"animation.mudkip.WALKSPEED_TEST": {
"loop": true,
"bones": {
"body": {
"position": [0, 0, "q.anim_time*90*-0.07"]
}
}
}
}
}
@@ -3,83 +3,173 @@
"animations": {
"animation.marshtomp.ground_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"torso": {
"rotation": [0, 0, 0]
"rotation": ["0+math.sin(q.anim_time*90*4)*-1", "math.sin(q.anim_time*90*2)*2", "math.sin(q.anim_time*90*2)*-1"],
"position": [0, "math.sin(q.anim_time*90*4-30)*-0.05", 0]
},
"chest": {
"rotation": [-2.5, 0, 0]
"rotation": ["0+math.sin(q.anim_time*90*4-30)*-1", "math.sin(q.anim_time*90*2-30)*1", "math.sin(q.anim_time*90*2-30)*-0.5"]
},
"neck": {
"rotation": ["0+math.sin(q.anim_time*90*4-30)*2.5", 0, 0]
},
"head": {
"rotation": [5, 0, 0]
"rotation": ["5+math.sin(q.anim_time*90*4-30)*-3", "math.sin(q.anim_time*90*2-30)*1", "math.sin(q.anim_time*90*2-30)*-1.5"]
},
"head_fin": {
"rotation": ["0+math.sin(q.anim_time*90*4-30)*-1.5", 0, 0]
},
"arm_left": {
"rotation": [7.5, 0, 27.5]
"rotation": [7.5, 0, "37.5+math.sin(q.anim_time*90*2)*-5"]
},
"arm_left2": {
"rotation": [0, 15, 2.5]
"rotation": [0, "15+math.sin(q.anim_time*90*2-30)*5", "2.5+math.sin(q.anim_time*90*2-60)*-5"]
},
"hand_left": {
"rotation": [0, 0, 5]
"rotation": [0, "0+math.sin(q.anim_time*90*2-120)*3", "10+math.sin(q.anim_time*90*2-150)*-2.5"]
},
"finger_front_left": {
"rotation": [0, 2.5, 15]
"rotation": [0, 0, "10+math.sin(q.anim_time*90*2-60)*-5"]
},
"finger_middle_left": {
"rotation": [0, 0, 10]
"rotation": [0, 0, "10+math.sin(q.anim_time*90*2-120)*-5"]
},
"finger_back_left": {
"rotation": [0, -5, 20]
"rotation": [0, 0, "10+math.sin(q.anim_time*90*2-180)*-5"]
},
"arm_right": {
"rotation": [7.5, 0, -27.5]
"rotation": [7.5, 0, "-37.5+math.sin(q.anim_time*90*2)*-5"]
},
"arm_right2": {
"rotation": [0, -15, -2.5]
"rotation": [0, "-15+math.sin(q.anim_time*90*2-30)*5", "-2.5+math.sin(q.anim_time*90*2-60)*-5"]
},
"hand_right": {
"rotation": [0, 0, -5]
"rotation": [0, "0+math.sin(q.anim_time*90*2-120)*3", "-10+math.sin(q.anim_time*90*2-150)*-2.5"]
},
"finger_front_right": {
"rotation": [0, -2.5, -15]
"rotation": [0, 0, "-10+math.sin(q.anim_time*90*2-60)*-5"]
},
"finger_middle_right": {
"rotation": [0, 0, -10]
"rotation": [0, 0, "-10+math.sin(q.anim_time*90*2-120)*-5"]
},
"finger_back_right": {
"rotation": [0, 5, -20]
"rotation": [0, 0, "-10+math.sin(q.anim_time*90*2-180)*-5"]
},
"tail_fin_left": {
"rotation": [-5, 45, 0]
"rotation": [-5, "45+math.sin(q.anim_time*90*2)*-12", 0]
},
"tail_fin_right": {
"rotation": [-5, -45, 0]
"rotation": [-5, "-45+math.sin(q.anim_time*90*2)*12", 0]
},
"leg_left": {
"rotation": [2.5, 0, -2.5]
"rotation": ["-2.5+math.sin(q.anim_time*90*2)*2.5", 0, 0],
"position": [0, "-0.05+math.sin(q.anim_time*90*2)*0.1", "0+math.sin(q.anim_time*90*2)*-0.1"]
},
"leg_left2": {
"rotation": ["2.5+math.sin(q.anim_time*90*2)*-2.5", 0, 0]
},
"leg_right": {
"rotation": ["-2.5+math.sin(q.anim_time*90*2)*-2.5", 0, 0],
"position": [0, "-0.05+math.sin(q.anim_time*90*2)*-0.1", "0+math.sin(q.anim_time*90*2)*0.1"]
},
"leg_right2": {
"rotation": ["2.5+math.sin(q.anim_time*90*2)*2.5", 0, 0]
}
}
},
"animation.marshtomp.battle_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"torso": {
"rotation": ["0+math.sin(q.anim_time*90*4)*-2", "math.sin(q.anim_time*90*2)*4", "math.sin(q.anim_time*90*2)*-2"],
"position": [0, "math.sin(q.anim_time*90*4)*0.05", 0]
},
"chest": {
"rotation": ["-2.5+math.sin(q.anim_time*90*4-30)*-1", "math.sin(q.anim_time*90*2-30)*4", "math.sin(q.anim_time*90*2-30)*-2.5"]
},
"head": {
"rotation": ["5+math.sin(q.anim_time*90*4-30)*-3", "math.sin(q.anim_time*90*2-30)*-6", "math.sin(q.anim_time*90*2-30)*5"]
},
"arm_left": {
"rotation": [7.5, 0, "27.5+math.sin(q.anim_time*90*2)*-7.5"]
},
"arm_left2": {
"rotation": [0, "15+math.sin(q.anim_time*90*2-30)*5", "2.5+math.sin(q.anim_time*90*2-30)*-5"]
},
"hand_left": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-90)*5", "5+math.sin(q.anim_time*90*2-90)*-7.5"]
},
"finger_front_left": {
"rotation": [0, 2.5, "15+math.sin(q.anim_time*90*2-120)*-10"]
},
"finger_middle_left": {
"rotation": [0, 0, "10+math.sin(q.anim_time*90*2-150)*-10"]
},
"finger_back_left": {
"rotation": [0, -5, "20+math.sin(q.anim_time*90*2-180)*-10"]
},
"arm_right": {
"rotation": [7.5, 0, "-27.5+math.sin(q.anim_time*90*2)*-7.5"]
},
"arm_right2": {
"rotation": [0, "-15+math.sin(q.anim_time*90*2-30)*5", "-2.5+math.sin(q.anim_time*90*2-30)*-5"]
},
"hand_right": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-90)*5", "-5+math.sin(q.anim_time*90*2-90)*-7.5"]
},
"finger_front_right": {
"rotation": [0, -2.5, "-15+math.sin(q.anim_time*90*2-120)*-10"]
},
"finger_middle_right": {
"rotation": [0, 0, "-10+math.sin(q.anim_time*90*2-150)*-10"]
},
"finger_back_right": {
"rotation": [0, 5, "-20+math.sin(q.anim_time*90*2-180)*-10"]
},
"tail_fin_left": {
"rotation": [-5, "45+math.sin(q.anim_time*90*2)*-12", 0]
},
"tail_fin_right": {
"rotation": [-5, "-45+math.sin(q.anim_time*90*2)*12", 0]
},
"leg_left": {
"rotation": [2.4905, "0.2178+math.sin(q.anim_time*90*2)*1.5", -2.49527]
},
"leg_left2": {
"rotation": [5, 0, 0]
},
"foot_left": {
"rotation": [-7.5, 0, 2.5]
"rotation": [-7.47178, "0.6518+math.sin(q.anim_time*90*2)*-1.5", 2.45744]
},
"leg_right": {
"rotation": [2.5, 0, 2.5]
"rotation": [2.4905, "-0.2178+math.sin(q.anim_time*90*2)*1.5", 2.49527]
},
"leg_right2": {
"rotation": [5, 0, 0]
},
"foot_right": {
"rotation": [-7.5, 0, -2.5]
}
}
},
"animation.marshtomp.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.marshtomp.cry"
"rotation": [-7.47178, "-0.6518+math.sin(q.anim_time*90*2)*-1.5", -2.45744]
},
"body": {
"position": [0, -0.15, 0]
},
"neck": {
"rotation": ["0+math.sin(q.anim_time*90*4-30)*2.5", 0, 0]
},
"head_fin": {
"rotation": ["0+math.sin(q.anim_time*90*4-30)*-1.5", 0, 0]
},
"eye_angry_left": {
"position": [0, 0, -0.1]
},
"eye_angry_right": {
"position": [0, 0, -0.1]
},
"jaw": {
"rotation": ["5+math.sin(q.anim_time*90*4-30)*-5", 0, 0]
}
}
},
@@ -162,6 +252,108 @@
"position": [0, 0, -0.1]
}
}
},
"animation.marshtomp.cry": {
"animation_length": 2,
"bones": {
"chest": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [-12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [-12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0417": {
"post": [-12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.4583": {
"post": [-1.53, 0, 0],
"lerp_mode": "catmullrom"
},
"1.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [27.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [17.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [40, 0, 0],
"lerp_mode": "catmullrom"
},
"1.4583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.4167": {
"effect": "pokemon.marshtomp.cry"
}
}
}
}
}
@@ -3,30 +3,33 @@
"animations": {
"animation.swampert.ground_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"position": [0, 1.75, 0]
},
"chest2": {
"rotation": [-12.5, 0, 0]
"rotation": ["-12.5+math.sin(q.anim_time*90*2-60)*0.75", 0, 0]
},
"neck": {
"rotation": [-5, 0, 0]
"rotation": ["-5+math.sin(q.anim_time*90*2-90)*1", "0+math.sin(q.anim_time*90*1-90)*-1", 0]
},
"leg_left": {
"rotation": [8.77647, -12.0131, -53.28718]
"rotation": ["8.7765+math.sin(q.anim_time*90*2)*-1.5", -12.0131, -53.28718],
"position": [0, "0+math.sin(q.anim_time*90*2)*-0.1", "0+math.sin(q.anim_time*90*2)*0.15"]
},
"leg_left2": {
"rotation": [4.54163, -0.2127, 45.09046]
"rotation": [4.5416, -0.2127, 45.09046]
},
"leg_left3": {
"rotation": [9.83802, -2.51058, 9.95791]
},
"foot_left": {
"rotation": [-27.58324, -3.55523, 20.16242]
"rotation": [-27.58324, "-3.5552+math.sin(q.anim_time*90*2)*-1.5", 20.16242]
},
"leg_right": {
"rotation": [8.77647, 12.0131, 53.2872]
"rotation": ["8.7765+math.sin(q.anim_time*90*2)*-1.5", 12.0131, 53.2872],
"position": [0, "0+math.sin(q.anim_time*90*2)*-0.1", "0+math.sin(q.anim_time*90*2)*0.15"]
},
"leg_right2": {
"rotation": [4.54163, 0.2127, -45.0905]
@@ -35,16 +38,155 @@
"rotation": [9.83802, 2.5106, -9.9579]
},
"foot_right": {
"rotation": [-27.58324, 3.5552, -20.1624]
"rotation": [-27.58324, "3.5552+math.sin(q.anim_time*90*2)*1.5", -20.1624]
},
"arm_left2": {
"rotation": [-4.36302, -31.26463, 17.62528]
"rotation": [-4.36302, -31.26463, "17.6253+math.sin(q.anim_time*90*2-90)*2"]
},
"arm_left3": {
"rotation": [1.80384, 2.38704, 35.42915]
"rotation": [1.80384, 2.38704, "35.4291+math.sin(q.anim_time*90*2-120)*2.5"]
},
"arm_left": {
"rotation": [-13.31914, -14.63639, 12.92638]
"rotation": [-13.31914, "-14.6364+math.sin(q.anim_time*90*2-60)*2", 12.92638]
},
"finger_front_left": {
"rotation": [0, "-37.5+math.sin(q.anim_time*90*2-120)*-2.5", 20]
},
"finger_middle_left": {
"rotation": [0, "-32.5+math.sin(q.anim_time*90*2-120)*-2.5", 0]
},
"finger_back_left": {
"rotation": [0, "-30+math.sin(q.anim_time*90*2-120)*-2.5", -27.5]
},
"fingers_left": {
"rotation": [0, 37.5, 0]
},
"arm_right": {
"rotation": [-13.31914, "14.6364+math.sin(q.anim_time*90*2-60)*-2", -12.9264]
},
"arm_right2": {
"rotation": [-4.33052, "31.2647+math.sin(q.anim_time*90*2-90)*2", -17.60892]
},
"arm_right3": {
"rotation": [1.80384, -2.387, "-35.4292+math.sin(q.anim_time*90*2-120)*-2.5"]
},
"fingers_right": {
"rotation": [0, -37.5, 0]
},
"finger_front_right": {
"rotation": [0, "37.5+math.sin(q.anim_time*90*2-120)*2.5", -20]
},
"finger_middle_right": {
"rotation": [0, "32.5+math.sin(q.anim_time*90*2-120)*2.5", 0]
},
"finger_back_right": {
"rotation": [0, "30+math.sin(q.anim_time*90*2-120)*2.5", 27.5]
},
"torso": {
"rotation": ["-5+math.sin(q.anim_time*90*2)*0.5", 0, 0],
"position": [0, "0+math.sin(q.anim_time*90*2+30)*-0.4", 0]
},
"chest": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-30)*1.5", 0, 0]
},
"hand_left": {
"rotation": [0, "-17.5+math.sin(q.anim_time*90*2-90)*-5", 0]
},
"finger_front_left2": {
"rotation": [0, "-12.5+math.sin(q.anim_time*90*2-150)*-5", 0]
},
"finger_middle_left2": {
"rotation": [0, "-10+math.sin(q.anim_time*90*2-150)*-5", 0]
},
"finger_back_left2": {
"rotation": [0, "-15+math.sin(q.anim_time*90*2-150)*-5", 0]
},
"hand_right": {
"rotation": [0, "17.5+math.sin(q.anim_time*90*2-90)*5", 0]
},
"finger_front_right2": {
"rotation": [0, "12.5+math.sin(q.anim_time*90*2-150)*5", 0]
},
"finger_middle_right2": {
"rotation": [0, "10+math.sin(q.anim_time*90*2-150)*5", 0]
},
"finger_back_right2": {
"rotation": [0, "15+math.sin(q.anim_time*90*2-150)*5", 0]
},
"check_left_spike_front": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*3", 0]
},
"check_left_spike_back": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*3", 0]
},
"check_right_spike_front": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*-3", 0]
},
"check_right_spike_back": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*-3", 0]
},
"eyebrow_left": {
"rotation": [0, "-2.5+math.sin(q.anim_time*90*2-60)*-2.5", 0]
},
"eyebrow_right": {
"rotation": [0, "2.5-math.sin(q.anim_time*90*2-60)*-2.5", 0]
},
"tail": {
"rotation": ["0+math.sin(q.anim_time*90*2-30)*-2.5", 0, 0]
},
"head": {
"rotation": ["12.5+math.sin(q.anim_time*90*2-90)*-2.5", "-0+math.sin(q.anim_time*90*1-90)*-0.5", 0]
}
}
},
"animation.swampert.battle_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"position": [0, 1.75, 0]
},
"chest2": {
"rotation": ["-12.5+math.sin(q.anim_time*90*2-60)*0.75", 0, 0]
},
"neck": {
"rotation": ["-5+math.sin(q.anim_time*90*2-90)*1", "0+math.sin(q.anim_time*90*1-90)*-1", 0]
},
"leg_left": {
"rotation": ["8.7765+math.sin(q.anim_time*90*2)*-1.5", -12.0131, -53.28718],
"position": [0, "0+math.sin(q.anim_time*90*2)*-0.1", "0+math.sin(q.anim_time*90*2)*0.15"]
},
"leg_left2": {
"rotation": [4.5416, -0.2127, 45.09046]
},
"leg_left3": {
"rotation": [9.83802, -2.51058, 9.95791]
},
"foot_left": {
"rotation": [-27.58324, "-3.5552+math.sin(q.anim_time*90*2)*-1.5", 20.16242]
},
"leg_right": {
"rotation": ["8.7765+math.sin(q.anim_time*90*2)*-1.5", 12.0131, 53.2872],
"position": [0, "0+math.sin(q.anim_time*90*2)*-0.1", "0+math.sin(q.anim_time*90*2)*0.15"]
},
"leg_right2": {
"rotation": [4.54163, 0.2127, -45.0905]
},
"leg_right3": {
"rotation": [9.83802, 2.5106, -9.9579]
},
"foot_right": {
"rotation": [-27.58324, "3.5552+math.sin(q.anim_time*90*2)*1.5", -20.1624]
},
"arm_left2": {
"rotation": [-4.71002, "-12.8789-math.sin(q.anim_time*90*2-90)*2", 28.88472]
},
"arm_left3": {
"rotation": [1.81234, "10.1983-math.sin(q.anim_time*90*2-30)*-5", 25.6704]
},
"arm_left": {
"rotation": [-33.31914, "-14.6364-math.sin(q.anim_time*90*2-60)*-2", 12.9264],
"position": [0, "0-math.sin(q.anim_time*90*2-30)*-0.3", 0]
},
"finger_front_left": {
"rotation": [0, -37.5, 20]
@@ -59,13 +201,14 @@
"rotation": [0, 37.5, 0]
},
"arm_right": {
"rotation": [-13.31914, 14.6364, -12.9264]
"rotation": [-33.31914, "14.6364+math.sin(q.anim_time*90*2-60)*-2", -12.9264],
"position": [0, "0-math.sin(q.anim_time*90*2-30)*-0.3", 0]
},
"arm_right2": {
"rotation": [-4.36302, 31.2646, -17.6253]
"rotation": [-4.71002, "12.8789+math.sin(q.anim_time*90*2-90)*2", -28.88472]
},
"arm_right3": {
"rotation": [1.80384, -2.387, -35.4292]
"rotation": [1.81234, "-10.1983+math.sin(q.anim_time*90*2-30)*-5", -25.6704]
},
"fingers_right": {
"rotation": [0, -37.5, 0]
@@ -80,37 +223,65 @@
"rotation": [0, 30, 27.5]
},
"torso": {
"rotation": [-2.5, 0, 0]
"rotation": ["12.5+math.sin(q.anim_time*90*2)*0.5", 0, 0],
"position": [0, "0+math.sin(q.anim_time*90*2+30)*-0.4", 0]
},
"chest": {
"rotation": [-7.5, 0, 0]
"rotation": ["-0+math.sin(q.anim_time*90*2-30)*1.5", 0, 0]
},
"hand_left": {
"rotation": [0, -17.5, 0]
"rotation": [0, "-17.5-math.sin(q.anim_time*90*2-60)*-2", 0]
},
"finger_front_left2": {
"rotation": [0, -12.5, 0]
"rotation": [0, "-12.5+math.sin(q.anim_time*90*2-150)*-5", 0]
},
"finger_middle_left2": {
"rotation": [0, -10, 0]
"rotation": [0, "-10+math.sin(q.anim_time*90*2-150)*-5", 0]
},
"finger_back_left2": {
"rotation": [0, -15, 0]
},
"head_angle": {
"rotation": [12.5, 0, 0]
"rotation": [0, "-15+math.sin(q.anim_time*90*2-150)*-5", 0]
},
"hand_right": {
"rotation": [0, 17.5, 0]
"rotation": [0, "17.5+math.sin(q.anim_time*90*2-60)*-2", 0]
},
"finger_front_right2": {
"rotation": [0, 12.5, 0]
"rotation": [0, "12.5+math.sin(q.anim_time*90*2-150)*5", 0]
},
"finger_middle_right2": {
"rotation": [0, 10, 0]
"rotation": [0, "10+math.sin(q.anim_time*90*2-150)*5", 0]
},
"finger_back_right2": {
"rotation": [0, 15, 0]
"rotation": [0, "15+math.sin(q.anim_time*90*2-150)*5", 0]
},
"check_left_spike_front": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*3", 0]
},
"check_left_spike_back": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*3", 0]
},
"check_right_spike_front": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*-3", 0]
},
"check_right_spike_back": {
"rotation": [0, "0+math.sin(q.anim_time*90*2-30)*-3", 0]
},
"eyebrow_left": {
"rotation": [0, "-2.5+math.sin(q.anim_time*90*2-60)*-2.5", 0]
},
"eyebrow_right": {
"rotation": [0, "2.5-math.sin(q.anim_time*90*2-60)*-2.5", 0]
},
"tail": {
"rotation": ["0+math.sin(q.anim_time*90*2-30)*-2.5", 0, 0]
},
"head": {
"rotation": ["-5+math.sin(q.anim_time*90*2-90)*-2.5", "math.sin(q.anim_time*90*1-90)*-0.5", 0]
},
"eye_angry_left": {
"position": [0, -0.1, 0]
},
"eye_angry_right": {
"position": [0, -0.1, 0]
}
}
},
@@ -233,14 +404,6 @@
}
}
},
"animation.swampert.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.swampert.cry"
}
}
},
"animation.swampert.blink": {
"animation_length": 0.1667,
"bones": {
@@ -322,6 +485,158 @@
"position": [0, -0.1, 0]
}
}
},
"animation.swampert.cry": {
"animation_length": 2.5,
"bones": {
"chest2": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5417": {
"post": [-6, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0417": {
"post": [-1, 0, 0],
"lerp_mode": "catmullrom"
},
"2.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"neck": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5417": {
"post": [-6, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0417": {
"post": [-1, 0, 0],
"lerp_mode": "catmullrom"
},
"2.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [-6, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"2.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, -0.1, 0]
},
"0.4167": {
"pre": [0, -0.1, 0],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, -0.1, 0]
},
"0.4167": {
"pre": [0, -0.1, 0],
"post": [0, 0, 0]
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [30, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [15, 0, 0],
"lerp_mode": "catmullrom"
},
"1.4167": {
"post": [40, 0, 0],
"lerp_mode": "catmullrom"
},
"1.8333": {
"post": [40, 0, 0],
"lerp_mode": "catmullrom"
},
"2.1667": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.4167": {
"effect": "pokemon.swampert.cry"
}
}
}
}
}
@@ -364,6 +364,14 @@
"rotation": [-22.5, 0, 0]
}
}
},
"animation.wurmple.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.wurmple.cry"
}
}
}
}
}
@@ -212,6 +212,14 @@
"position": [0, 0, -0.1]
}
}
},
"animation.silcoon.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.silcoon.cry"
}
}
}
}
}
@@ -361,6 +361,14 @@
"rotation": [0, 20, 0]
}
}
},
"animation.beautifly.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.beautifly.cry"
}
}
}
}
}
@@ -194,6 +194,14 @@
"position": [0, 0, -0.1]
}
}
},
"animation.cascoon.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.cascoon.cry"
}
}
}
}
}
@@ -255,6 +255,30 @@
"position": [0, 0, -0.1]
}
}
},
"animation.dustox.cry": {
"animation_length": 1,
"bones": {
"mouth_closed_smile": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"0.625": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"0.625": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0833": {
"effect": "pokemon.dustox.cry"
}
}
}
}
}
@@ -149,6 +149,14 @@
"rotation": [0, 0, 22.5]
}
}
},
"animation.surskit.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.surskit.cry"
}
}
}
},
"geckolib_format_version": 2
@@ -158,6 +158,11 @@
"0.75": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.masquerain.cry"
}
}
}
},
@@ -447,6 +447,11 @@
"1.5": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.starly.cry"
}
}
}
}
@@ -331,6 +331,11 @@
"1.5": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.staravia.cry"
}
}
},
"animation.staravia.blink": {
@@ -464,6 +464,11 @@
"1.5": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.combee.cry"
}
}
}
}
@@ -824,6 +824,14 @@
}
}
}
},
"animation.vespiquen.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.vespiquen.cry"
}
}
}
}
}
@@ -589,7 +589,7 @@
"animation.frogadier.battle_idle": {
"loop": true,
"bones": {
"frogadier": {
"body": {
"position": [0, -8, 0]
},
"torso": {
@@ -400,6 +400,30 @@
"position": [0, 0, -0.1]
}
}
},
"animation.helioptile.cry": {
"animation_length": 1.2083,
"bones": {
"mouth_closed": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0833": {
"effect": "pokemon.helioptile.cry"
}
}
}
}
}
@@ -563,6 +563,14 @@
"position": [0.1, 0, 0]
}
}
},
"animation.heliolisk.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.heliolisk.cry"
}
}
}
}
}
@@ -125,6 +125,11 @@
"0.5417": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0417": {
"effect": "pokemon.grubbin.cry"
}
}
},
"animation.grubbin.physical": {
@@ -38,6 +38,11 @@
"0.625": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0833": {
"effect": "pokemon.charjabug.cry"
}
}
},
"animation.charjabug.ditto_face": {
@@ -326,6 +326,14 @@
"position": [0, 0, -0.1]
}
}
},
"animation.runerigus.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0": {
"effect": "pokemon.runerigus.cry"
}
}
}
}
}
@@ -21,12 +21,12 @@
"rotation": [0, -45, 0]
},
"tail": {
"rotation": [50, 0, 0]
"rotation": ["50-math.sin(q.anim_time*90*2-60)*-3", 0, 0]
},
"toe_inner_left": {
"toe_front_inner_left": {
"rotation": [0, 5, 0]
},
"toe_outer_left": {
"toe_front_outer_left": {
"rotation": [0, -5, 0]
},
"neckflap_left": {
@@ -44,11 +44,372 @@
},
"wing_right3": {
"rotation": [0, 45, 0]
},
"torso": {
"rotation": ["-math.sin(q.anim_time*90*2-90)*1", 0, "math.sin(q.anim_time*90*1-90)*1"],
"position": [0, "math.sin(q.anim_time*90*2)*0.1", 0]
},
"neck": {
"rotation": ["-0-math.sin(q.anim_time*90*2-180)*1", 0, 0]
},
"head": {
"rotation": ["-0-math.sin(q.anim_time*90*2-90)*-2", 0, 0]
},
"hair": {
"rotation": ["-0-math.sin(q.anim_time*90*2-150)*-2", 0, 0]
}
}
},
"animation.squawkabilly.ground_walk": {
"loop": true,
"animation_length": 0.75,
"bones": {
"hairstrand": {
"rotation": [7.5, 0, 12.5]
},
"hairstrand2": {
"rotation": [-17.5, 0, 0]
},
"wing_left": {
"rotation": [155.5391, -73.26807, -64.02788],
"position": [0, -1.5, -2]
},
"wing_left2": {
"rotation": [0, 45, 0]
},
"wing_left3": {
"rotation": [0, -45, 0]
},
"tail": {
"rotation": ["50-math.cos(q.anim_time*90*16/3*2)*5", 0, 0]
},
"toe_front_inner_left": {
"rotation": {
"0.0": [-55, 10, -7.5],
"0.125": {
"pre": [7.5, 15, 0],
"post": [7.5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, 15, 0],
"0.625": [0, 15, 0],
"0.75": [-55, 10, -7.5]
},
"position": {
"0.0": [0, -0.75, 0.85],
"0.125": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [0, -0.75, 0.85]
}
},
"toe_front_outer_left": {
"rotation": {
"0.0": [-51.5, -2.5, 10],
"0.125": {
"pre": [5, -15, 0],
"post": [5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, -15, 0],
"0.625": [0, -15, 0],
"0.75": [-51.5, -2.5, 10]
},
"position": {
"0.0": [0, -0.75, 0.85],
"0.125": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [0, -0.75, 0.85]
}
},
"neckflap_left": {
"rotation": [0, 0, "15+math.cos(q.anim_time*90*16/3*2-60)*-2.5"]
},
"neckflap_right": {
"rotation": [0, 0, "-15-math.cos(q.anim_time*90*16/3*2-60)*-2.5"]
},
"wing_right": {
"rotation": [153.0391, 73.26807, 64.02788],
"position": [0, -2, -3]
},
"wing_right2": {
"rotation": [0, -45, 0]
},
"wing_right3": {
"rotation": [0, 45, 0]
},
"torso": {
"rotation": ["1-math.cos(q.anim_time*90*16/3*2)*-2", "-math.sin(q.anim_time*90*16/3+60)*3", "-1+math.sin(q.anim_time*90*16/3+30)*-4"],
"position": [0, "math.sin(q.anim_time*90*16/3*2)*0.2", 0]
},
"coat_left": {
"rotation": ["-0-math.cos(q.anim_time*90*16/3*2)*-2.5", 0, "0+math.cos(q.anim_time*90*8/3*2)*5"]
},
"coat_right": {
"rotation": ["-0-math.cos(q.anim_time*90*16/3*2)*-2.5", 0, "0-math.cos(q.anim_time*90*8/3*2)*-5"]
},
"neck": {
"rotation": ["-math.cos(q.anim_time*90*16/3*2)*-2.5", "-math.sin(q.anim_time*90*16/3+60)*-3", "math.sin(q.anim_time*90*16/3+30)*3"]
},
"head": {
"rotation": ["-0-math.cos(q.anim_time*90*16/3*2)*3", 0, 0]
},
"hair": {
"rotation": ["-0-math.cos(q.anim_time*90*16/3*2-60)*4", 0, 0]
},
"leg_left": {
"rotation": {
"0.0": [25, -17.5, 0],
"0.125": {
"pre": [21.25, -12.5, 0],
"post": [21.25, -12.5, 0],
"lerp_mode": "catmullrom"
},
"0.375": [-40, -5, 0],
"0.75": [25, -17.5, 0]
},
"position": {
"0.0": [0.3, 0.1, 0.6],
"0.0417": [0.23, 0.25, 0.71],
"0.125": {
"pre": [0, 0.68, -0.08],
"post": [0, 0.68, -0.08],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0.97, -1.41],
"lerp_mode": "catmullrom"
},
"0.375": [0, -0.5, -2.15],
"0.5": [0, -0.19, -1.02],
"0.5833": [0, -0.07, -0.3],
"0.625": [0, -0.02, 0.21],
"0.7083": [0.1, 0.215, 0.43],
"0.75": [0.3, 0.1, 0.6]
}
},
"leg_left2": {
"rotation": {
"0.0": [0, 0, 0],
"0.125": {
"pre": [-30.83, 0, 0],
"post": [-30.83, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-2.65, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": [12.5, 0, 0],
"0.75": [0, 0, 0]
}
},
"foot_left": {
"rotation": {
"0.0": [27.5, 0, -5],
"0.125": {
"pre": [20.17, 0, 0],
"post": [20.17, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [12.596, 0.6637, -1.3486],
"lerp_mode": "catmullrom"
},
"0.375": [28, 0, 0],
"0.625": [-7.33, 0, 0],
"0.75": [27.5, 0, -5]
},
"position": {
"0.0": [0, 0.25, 0],
"0.125": [0, 0, 0],
"0.375": [0, 0, 0],
"0.625": [0, 0.17, 0],
"0.75": [0, 0.25, 0]
}
},
"toe_back_outer_left": {
"rotation": {
"0.0": [-20, 0, 0],
"0.2083": {
"pre": [-8.33, 0, 0],
"post": [-8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [-20, 0, 0]
}
},
"leg_right": {
"rotation": {
"0.0": [-40, 5, 0],
"0.375": [25, 17.5, 0],
"0.5": {
"pre": [21.25, 12.5, 0],
"post": [21.25, 12.5, 0],
"lerp_mode": "catmullrom"
},
"0.75": [-40, 5, 0]
},
"position": {
"0.0": [0, -0.5, -2.15],
"0.125": [0, -0.19, -1.02],
"0.2083": [0, -0.07, -0.3],
"0.25": [0, -0.02, 0.21],
"0.3333": [-0.1, 0.215, 0.43],
"0.375": [-0.3, 0.1, 0.6],
"0.4167": [-0.23, 0.25, 0.71],
"0.5": {
"pre": [0, 0.68, -0.08],
"post": [0, 0.68, -0.08],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [0, 0.97, -1.41],
"lerp_mode": "catmullrom"
},
"0.75": [0, -0.5, -2.15]
}
},
"leg_right2": {
"rotation": {
"0.0": [12.5, 0, 0],
"0.375": [0, 0, 0],
"0.5": {
"pre": [-30.83, 0, 0],
"post": [-30.83, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-2.65, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": [12.5, 0, 0]
}
},
"foot_right": {
"rotation": {
"0.0": [28, 0, 0],
"0.25": [-7.33, 0, 0],
"0.375": [27.5, 0, 5],
"0.5": {
"pre": [20.17, 0, 0],
"post": [20.17, 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [12.596, -0.6637, 1.3486],
"lerp_mode": "catmullrom"
},
"0.75": [28, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0.17, 0],
"0.375": [0, 0.25, 0],
"0.5": [0, 0, 0],
"0.75": [0, 0, 0]
}
},
"toe_back_inner_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [-20, 0, 0],
"0.5833": {
"pre": [-8.33, 0, 0],
"post": [-8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, 0, 0]
}
},
"toe_front_inner_right": {
"rotation": {
"0.0": [0, -15, 0],
"0.25": [0, -15, 0],
"0.375": [-55, -10, 7.5],
"0.5": {
"pre": [7.5, -15, 0],
"post": [7.5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [5, -15, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, -15, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [0, -0.75, 0.85],
"0.5": [0, 0, 0],
"0.75": [0, 0, 0]
}
},
"toe_front_outer_right": {
"rotation": {
"0.0": [0, 15, 0],
"0.25": [0, 15, 0],
"0.375": [-51.5, 2.5, -10],
"0.5": {
"pre": [5, 15, 0],
"post": [5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [5, 15, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, 15, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [0, -0.75, 0.85],
"0.5": [0, 0, 0],
"0.75": [0, 0, 0]
}
},
"toe_back_inner_left": {
"rotation": {
"0.0": [-20, 0, 0],
"0.2083": {
"pre": [-8.33, 0, 0],
"post": [-8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": [0, 0, 0],
"0.625": [0, 0, 0],
"0.75": [-20, 0, 0]
}
},
"toe_back_inner_right3": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0],
"0.375": [-20, 0, 0],
"0.5833": {
"pre": [-8.33, 0, 0],
"post": [-8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": [0, 0, 0]
}
}
}
},
"animation.squawkabilly.cry": {
"animation_length": 1.25,
"animation_length": 2,
"bones": {
"neck": {
"rotation": {
@@ -56,15 +417,27 @@
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [10, 0, 0],
"0.25": {
"post": [12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [10, 0, 0],
"0.5": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [8.33, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.9167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
@@ -76,15 +449,27 @@
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [-15, 0, 0],
"0.25": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [-15, 0, 0],
"0.5": {
"post": [-20, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [-12.78, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-27.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.75": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
@@ -96,19 +481,118 @@
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"0.25": {
"post": [25, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [25, 0, 0],
"0.5": {
"post": [47.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [20, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [62.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"torso": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [-7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.9167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"hair": {
"rotation": {
"0.0833": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [-20, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [-12.78, 0, 0],
"lerp_mode": "catmullrom"
},
"1.3333": {
"post": [-27.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.8333": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.8333": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"1.0": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.8333": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"1.0": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
}
},
"sound_effects": {
@@ -126,18 +610,205 @@
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": [0.1, 0, -0.1],
"0.1667": [0, 0, 0]
"0.1667": {
"pre": [0.1, 0, -0.1],
"post": [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]
"0.1667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
}
}
},
"animation.squawkabilly.air_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"position": ["-math.sin(q.anim_time*90*3-45)*0.5", "math.sin(q.anim_time*90*6-45)*1.5", "math.sin(q.anim_time*90*6-45)*1/2"]
},
"coat_left": {
"rotation": ["-0-math.sin(q.anim_time*90*6-60)*3", 0, "0+math.sin(q.anim_time*90*6-90)*5"]
},
"coat_right": {
"rotation": ["-0-math.sin(q.anim_time*90*6-60)*3", 0, "-0-math.sin(q.anim_time*90*6-90)*5"]
},
"wing_left": {
"rotation": ["25-math.sin(q.anim_time*90*6-90)*6", 0, "math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_left2": {
"rotation": [0, 0, "20+math.sin(q.anim_time*90*6-45)*30"]
},
"wing_left3": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*6-75)*30"]
},
"wing_right": {
"rotation": ["25-math.sin(q.anim_time*90*6-90)*6", 0, "-math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_right2": {
"rotation": [0, 0, "-20-math.sin(q.anim_time*90*6-45)*30"]
},
"wing_right3": {
"rotation": [0, 0, "-0-math.sin(q.anim_time*90*6-75)*30"]
},
"tail": {
"rotation": ["15-math.sin(q.anim_time*90*6-30)*7", 0, 0]
},
"neck": {
"rotation": ["5-math.sin(q.anim_time*90*6-140)*-1", 0, "math.sin(q.anim_time*90*3-00)*-1"]
},
"head": {
"rotation": ["-math.sin(q.anim_time*90*6-110)*3", 0, "math.sin(q.anim_time*90*3-120)*-2"]
},
"hair": {
"rotation": ["-0-math.sin(q.anim_time*90*6-170)*5", 0, 0]
},
"leg_left": {
"rotation": [-67.5, 0, -2.5]
},
"foot_left": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", -10, "math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_outer_left": {
"rotation": [-30, 0, 0]
},
"toe_front_inner_left": {
"rotation": [30, 0, 0]
},
"toe_front_outer_left": {
"rotation": [30, 0, 0]
},
"leg_right": {
"rotation": [-67.5, 0, 2.5]
},
"foot_right": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", 10, "-math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_inner_right": {
"rotation": [-30, 0, 0]
},
"toe_front_inner_right": {
"rotation": [30, 0, 0]
},
"toe_front_outer_right": {
"rotation": [30, 0, 0]
},
"toe_back_inner_left": {
"rotation": [-30, 0, 0]
},
"toe_back_inner_right3": {
"rotation": [-30, 0, 0]
}
},
"timeline": {
"0.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"1.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"3.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"4.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};"
}
},
"animation.squawkabilly.air_fly": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": [25, 0, 0],
"position": ["-math.sin(q.anim_time*90*3-45)*0.5", "math.sin(q.anim_time*90*6-45)*1.5", "math.sin(q.anim_time*90*6-45)*1/2"]
},
"coat_left": {
"rotation": ["-0-math.sin(q.anim_time*90*6-60)*3", 0, "0+math.sin(q.anim_time*90*6-90)*5"]
},
"coat_right": {
"rotation": ["-0-math.sin(q.anim_time*90*6-60)*3", 0, "-0-math.sin(q.anim_time*90*6-90)*5"]
},
"wing_left": {
"rotation": ["-0-math.sin(q.anim_time*90*6-90)*6", -5, "math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_left2": {
"rotation": [0, 0, "20+math.sin(q.anim_time*90*6-45)*30"]
},
"wing_left3": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*6-75)*30"]
},
"wing_right": {
"rotation": ["-0-math.sin(q.anim_time*90*6-90)*6", 5, "-math.sin(q.anim_time*90*6)*65"],
"position": [0, "math.sin(q.anim_time*90*6)*-1", 0]
},
"wing_right2": {
"rotation": [0, 0, "-20-math.sin(q.anim_time*90*6-45)*30"]
},
"wing_right3": {
"rotation": [0, 0, "-0-math.sin(q.anim_time*90*6-75)*30"]
},
"tail": {
"rotation": ["15-math.sin(q.anim_time*90*6-30)*7", 0, 0]
},
"neck": {
"rotation": ["25-math.sin(q.anim_time*90*6-140)*-1", 0, "math.sin(q.anim_time*90*3-00)*-1"]
},
"head": {
"rotation": ["-50-math.sin(q.anim_time*90*6-110)*3", 0, "math.sin(q.anim_time*90*3-120)*-2"]
},
"hair": {
"rotation": ["-0-math.sin(q.anim_time*90*6-170)*5", 0, 0]
},
"leg_left": {
"rotation": [-67.5, 0, -2.5]
},
"foot_left": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", -10, "math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_outer_left": {
"rotation": [-30, 0, 0]
},
"toe_front_inner_left": {
"rotation": [30, 0, 0]
},
"toe_front_outer_left": {
"rotation": [30, 0, 0]
},
"leg_right": {
"rotation": [-67.5, 0, 2.5]
},
"foot_right": {
"rotation": ["40-math.sin(q.anim_time*90*6-30)*-5", 10, "-math.sin(q.anim_time*90*3-150)*6"]
},
"toe_back_inner_right": {
"rotation": [-30, 0, 0]
},
"toe_front_inner_right": {
"rotation": [30, 0, 0]
},
"toe_front_outer_right": {
"rotation": [30, 0, 0]
},
"toe_back_inner_left": {
"rotation": [-30, 0, 0]
},
"toe_back_inner_right3": {
"rotation": [-30, 0, 0]
}
},
"timeline": {
"0.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"1.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"2.6667": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"3.3333": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};",
"4.0": "q.has_entity?{q.sound('animation.plumage.wing_flap.small');};"
}
}
}
}
@@ -68,7 +68,12 @@
"name": "head",
"parent": "neck3",
"pivot": [0, 32.86868, -14.9296],
"rotation": [-90, 0, 0],
"rotation": [-90, 0, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 32.86868, -14.9296],
"cubes": [
{"origin": [-2.5, 29.75372, -22.00071], "size": [5, 6, 8], "uv": [174, 92]},
{"origin": [-2.51, 34.75372, -22.00071], "size": [1, 1, 3], "inflate": 0.03, "uv": [1, 217]},
@@ -77,7 +82,7 @@
},
{
"name": "eyes",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 33.75372, -20.50071]
},
{
@@ -226,7 +231,7 @@
},
{
"name": "beak",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 33.35372, -22.50071],
"rotation": [17.5, 0, 0],
"cubes": [
@@ -276,7 +281,7 @@
},
{
"name": "crest",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 35.85372, -18.60071],
"rotation": [-5, 0, 0]
},
@@ -322,7 +327,7 @@
},
{
"name": "jaw",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 31.85372, -22.40071],
"rotation": [5, 0, 0],
"cubes": [
@@ -340,7 +345,7 @@
},
{
"name": "locator_head",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 36, -20],
"locators": {
"head": [0, 36, -20]
@@ -348,7 +353,7 @@
},
{
"name": "locator_item_hat",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 39, -18],
"locators": {
"item_hat": [0, 39, -18]
@@ -356,7 +361,7 @@
},
{
"name": "locator_item_face",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 34.25, -22],
"locators": {
"item_face": [0, 34.25, -22]
@@ -364,7 +369,7 @@
},
{
"name": "locator_face",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 31, -34],
"locators": {
"face": [0, 31, -34]
@@ -372,7 +377,7 @@
},
{
"name": "locator_mouth",
"parent": "head",
"parent": "head_ai",
"pivot": [0, 31.75, -20],
"locators": {
"mouth": [0, 31.75, -20]
@@ -7,8 +7,8 @@
"texture_width": 256,
"texture_height": 128,
"visible_bounds_width": 6,
"visible_bounds_height": 4,
"visible_bounds_offset": [0, 1, 0]
"visible_bounds_height": 5,
"visible_bounds_offset": [0, 1.5, 0]
},
"bones": [
{
@@ -252,7 +252,7 @@
"name": "head_correction",
"parent": "head",
"pivot": [0, 14.25, -14],
"rotation": [-42.5, 0, 0]
"rotation": [42.5, 0, 0]
},
{
"name": "head_ai",
@@ -263,6 +263,7 @@
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 14.25, -15],
"rotation": [-90, 0, 0],
"cubes": [
{"origin": [-7, 3.5, -21.5], "size": [14, 15, 6], "inflate": 0.01, "uv": [0, 0]},
{"origin": [-7, 10.5, -15.5], "size": [14, 8, 3], "inflate": 0.01, "uv": [40, 0]},
@@ -68,7 +68,7 @@
"parent": "torso",
"pivot": [0, 13, 2],
"locators": {
"seat": [0, 13, 2]
"seat_1": [0, 13, 2]
}
},
{
@@ -266,23 +266,41 @@
]
},
{
"name": "toe_back_left",
"name": "toe_back_inner_left",
"parent": "foot_left",
"pivot": [1.25, 1.92365, 1.01519],
"pivot": [0.75, 1.92365, 1.01519],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [1.25, -0.07635, 1.01519], "size": [0, 1, 1], "inflate": 0.01, "uv": [0, 18]}
{"origin": [0.75, -0.07635, 1.01519], "size": [0, 1, 1], "inflate": 0.01, "uv": [0, 18]}
]
},
{
"name": "claw_back_left",
"parent": "toe_back_left",
"pivot": [1.25, 1.92365, 2.01519],
"name": "toe_back_inner_left2",
"parent": "toe_back_inner_left",
"pivot": [0.75, 1.92365, 2.01519],
"cubes": [
{"origin": [1.25, -0.07635, 2.01519], "size": [0, 1, 1], "uv": [4, 14]}
{"origin": [0.75, -0.07635, 2.01519], "size": [0, 1, 1], "uv": [4, 14]}
]
},
{
"name": "toe_inner_left",
"name": "toe_back_outer_left",
"parent": "foot_left",
"pivot": [1.75, 1.92365, 1.01519],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [1.75, -0.07635, 1.01519], "size": [0, 1, 1], "inflate": 0.01, "uv": [0, 18]}
]
},
{
"name": "toe_back_outer_left2",
"parent": "toe_back_outer_left",
"pivot": [1.75, 1.92365, 2.01519],
"cubes": [
{"origin": [1.75, -0.07635, 2.01519], "size": [0, 1, 1], "uv": [4, 14]}
]
},
{
"name": "toe_front_inner_left",
"parent": "foot_left",
"pivot": [1.25, 1.92365, -0.98481],
"rotation": [0, 12.5, 0],
@@ -291,15 +309,15 @@
]
},
{
"name": "claw_inner_left",
"parent": "toe_inner_left",
"name": "toe_front_inner_left2",
"parent": "toe_front_inner_left",
"pivot": [0.75, 1.92365, -1.98481],
"cubes": [
{"origin": [0.75, -0.07635, -2.98481], "size": [0, 1, 1], "uv": [4, 13]}
]
},
{
"name": "toe_outer_left",
"name": "toe_front_outer_left",
"parent": "foot_left",
"pivot": [1.25, 1.92365, -0.98481],
"rotation": [0, -12.5, 0],
@@ -308,8 +326,8 @@
]
},
{
"name": "claw_outer_left",
"parent": "toe_outer_left",
"name": "toe_front_outer_left2",
"parent": "toe_front_outer_left",
"pivot": [1.75, 1.92365, -1.98481],
"cubes": [
{"origin": [1.75, -0.07635, -2.98481], "size": [0, 1, 1], "uv": [4, 5]}
@@ -343,23 +361,41 @@
]
},
{
"name": "toe_back_right",
"name": "toe_back_inner_right",
"parent": "foot_right",
"pivot": [-1.25, 1.92365, 1.01519],
"pivot": [-0.75, 1.92365, 1.01519],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [-1.25, -0.07635, 1.01519], "size": [0, 1, 1], "inflate": 0.01, "uv": [0, 5]}
{"origin": [-0.75, -0.07635, 1.01519], "size": [0, 1, 1], "inflate": 0.01, "uv": [0, 5]}
]
},
{
"name": "claw_back_right",
"parent": "toe_back_right",
"pivot": [-1.25, 1.92365, 2.01519],
"name": "toe_back_inner_right2",
"parent": "toe_back_inner_right",
"pivot": [-0.75, 1.92365, 2.01519],
"cubes": [
{"origin": [-1.25, -0.07635, 2.01519], "size": [0, 1, 1], "uv": [4, 4]}
{"origin": [-0.75, -0.07635, 2.01519], "size": [0, 1, 1], "uv": [4, 4]}
]
},
{
"name": "toe_inner_right",
"name": "toe_back_inner_right3",
"parent": "foot_right",
"pivot": [-1.75, 1.92365, 1.01519],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [-1.75, -0.07635, 1.01519], "size": [0, 1, 1], "inflate": 0.01, "uv": [0, 5]}
]
},
{
"name": "toe_back_inner_right4",
"parent": "toe_back_inner_right3",
"pivot": [-1.75, 1.92365, 2.01519],
"cubes": [
{"origin": [-1.75, -0.07635, 2.01519], "size": [0, 1, 1], "uv": [4, 4]}
]
},
{
"name": "toe_front_inner_right",
"parent": "foot_right",
"pivot": [-1.25, 1.92365, -0.98481],
"rotation": [0, -12.5, 0],
@@ -368,15 +404,15 @@
]
},
{
"name": "claw_inner_right",
"parent": "toe_inner_right",
"name": "toe_front_inner_right2",
"parent": "toe_front_inner_right",
"pivot": [-0.75, 1.92365, -1.98481],
"cubes": [
{"origin": [-0.75, -0.07635, -2.98481], "size": [0, 1, 1], "uv": [4, 0]}
]
},
{
"name": "toe_outer_right",
"name": "toe_front_outer_right",
"parent": "foot_right",
"pivot": [-1.25, 1.92365, -0.98481],
"rotation": [0, 12.5, 0],
@@ -385,8 +421,8 @@
]
},
{
"name": "claw_outer_right",
"parent": "toe_outer_right",
"name": "toe_front_outer_right2",
"parent": "toe_front_outer_right",
"pivot": [-1.75, 1.92365, -1.98481],
"cubes": [
{"origin": [-1.75, -0.07635, -2.98481], "size": [0, 1, 1], "uv": [0, 0]}
@@ -846,6 +846,14 @@
"cubes": [
{"origin": [-2, -1, 27], "size": [4, 1, 4], "inflate": -0.01, "uv": [104, 47]}
]
},
{
"name": "locator_seat_1",
"parent": "surfboard",
"pivot": [0, 14.5, 3],
"locators": {
"seat_1": [19, 1.5, 0]
}
}
]
}

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