Compare commits

..
Author SHA1 Message Date
Cyrus 45386d2c7c Closes #1715 2025-10-09 11:32:32 -07:00
Polymeta fddb203db3 Merge branch 'fix-aprijuice-crash' into 'main'
Aprijuice feeding crash

Closes #1712

See merge request cable-mc/cobblemon!1887
2025-10-03 16:14:39 +00:00
lion 8a8cace5e8 Aprijuice feeding crash 2025-10-03 16:14:38 +00:00
Polymeta 5f5b4ee3c1 Merge branch 'implement_pokemon' into 'main'
Implement pokemon

See merge request cable-mc/cobblemon!1890
2025-10-03 08:19:57 +00:00
Paul 8aa9e0191f Shulker Boxes and Traveler's Backpacks cannot be held by Pokémon and make the PC file 5000000gb large anymore 2025-10-03 16:43:35 +10:00
Test 9d84cbb3ac Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-10-02 22:35:54 -04:00
Test 8e730f2b5c fix ride stat exceeding limit 2025-10-02 22:35:24 -04:00
Hiroku 7b5809fd55 Merge branch 'aprijuice-feeding-crash-fix' into 'main'
Aprijuice feeding crash fix

Closes #1712

See merge request cable-mc/cobblemon!1891
2025-10-03 01:22:09 +00:00
PieDuck bc682ddf62 Removes comments 2025-10-03 00:57:04 +01:00
PieDuck 990ead0544 Fixes ConcurrentModificationException crash when feeding pokemon aprijuice 2025-10-03 00:55:38 +01:00
Carmendar 4cf55dc95d Merge branch 'main' into implement_pokemon 2025-10-02 17:54:36 -05:00
Polymeta 27a9f3c704 Merge branch 'ride-settings-network-fixes-electric-boogaloo' into 'main'
Make RideSettingsSyncHandler be correctly sided

See merge request cable-mc/cobblemon!1889
2025-10-02 20:47:01 +00:00
Nadja Reitzenstein 83aba7e4a6 Make RideSettingsSyncHandler be correctly sided 2025-10-02 18:57:37 +02:00
Landon db10ae2183 Merge branch 'riding-behaviour-network-fixes' into 'main'
Make RidingBehaviourSettings::encode/decode symmetric

See merge request cable-mc/cobblemon!1888
2025-10-02 15:39:53 +00:00
Nadja Reitzenstein 548b8522a8 Make RidingBehaviourSettings::encode/decode symmetric
Having the encode/decode functionality symmetric is the expected behaviour and not doing so will introduce a lot of accidental bugs when people assume them to be. Case in point: `RideSettingsSyncPacket.kt` (which this commit notably *does not touch*) expected them to be and was thus entirely broken.
2025-10-02 16:02:24 +02:00
Polymeta 4791b146dc Merge branch 'hotfix-BufferUtils-NPE' into 'main'
Fix a logic error in write-/readNullable resulting in NPE on server joins.

See merge request cable-mc/cobblemon!1886
2025-10-02 13:43:18 +00:00
Nadja Reitzenstein b7a9931393 Fix a logic error in write-/readNullable resulting in NPE on server joins.
This error occurs because `writeNullable` will write `true` if the encoded value is `null` while `readNullable` will treat a `true` value as a value being present. Since it makes more sense to have a true value as a go-ahead this commit changes the behaviour of `writeNullable` to write `true` if a value is present and `false` if a value is `null`
2025-10-02 15:20:33 +02:00
Polymeta 9a35a11440 Merge branch 'the-case-of-disappearing-cubes' into 'main'
The Case of Disappearing Cubes

See merge request cable-mc/cobblemon!1883
2025-10-02 10:46:15 +00:00
Polymeta 6d4a50cee2 Merge branch 'cooking-pot-hopper-bugfix' into 'main'
Fixed bug with seasonings and hoppers in the campfire cooking pot

See merge request cable-mc/cobblemon!1885
2025-10-02 08:16:43 +00:00
PieDuck 818a637897 Merge branch cobblemon:main into cooking-pot-hopper-bugfix 2025-10-01 22:34:45 +01:00
Polymeta 4c96ab9b28 Merge branch 'Carm-Signfix' into 'main'
Added missing Saccharine sign loot table.

See merge request cable-mc/cobblemon!1884
2025-10-01 17:12:08 +00:00
PieDuck d5a316b9ae Fixed bug with seasonings and hoppers in the campfire cooking pot 2025-10-01 17:29:29 +01:00
Carmendar 87e32f0e9b Added missing Saccharine sign loot table. 2025-09-30 23:59:15 -05:00
GenotypeXD-Dev 0686428138 Implemented Elgyem, and Beheeyem remodels 2025-09-29 23:47:04 -05:00
GenotypeXD-Dev f05e6008e5 Ho-oh Fixes 2025-09-29 13:33:00 -05:00
Gertimoshka 53372e5400 Fixed a very specific case of how a model was made causing dissapearing cubes ingame 2025-09-29 20:15:14 +03:00
Polymeta 2fbb1f354c Merge branch '#1568-npcdelete' into 'main'
changes to /npcdelete uuid prameter and console support

Closes #1568

See merge request cable-mc/cobblemon!1851
2025-09-29 13:13:46 +00:00
Cyrus bf06476558 changes to /npcdelete uuid prameter and console support 2025-09-29 13:13:46 +00:00
Paul 2e3a742477 Merge remote-tracking branch 'origin/lang-updates' 2025-09-29 19:45:46 +10:00
Watuneni iteite 94c7542d2c Translated using Weblate (Japanese)
Currently translated at 86.7% (7693 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-29 09:27:58 +00:00
Polymeta fa2b6b5996 Merge branch 'regional-food-use-fix' into 'main'
Small fixes

Closes #1708, #1689, #1696, #1710, and #1711

See merge request cable-mc/cobblemon!1877
2025-09-29 08:13:44 +00:00
Watuneni iteite 8e77dc70f6 Translated using Weblate (Japanese)
Currently translated at 86.7% (7692 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-29 07:04:26 +00:00
Hiroku 51e3748adb Merge branch 'NoMoreAwkwardSurfaceSwimmingPlz' into 'main'
Fix Awkward water swimming

See merge request cable-mc/cobblemon!1882
2025-09-29 05:50:14 +00:00
Hiroku d8cf2701c7 Merge branch 'sterr/sigh-need-a-new-branch-for-this' into 'main'
Remove an unused sound from sounds.json

See merge request cable-mc/cobblemon!1881
2025-09-29 05:07:36 +00:00
Carmendar 4450164d9c Garchomp can swim in liquid water now. 2025-09-28 23:56:10 -05:00
JazzMcNade 31b7c83369 Merge branch 'main' into NoMoreAwkwardSurfaceSwimmingPlz 2025-09-28 22:50:07 -05:00
JazzMcNade a170123e2c Enforce minimum depth requirement for swim wander, fix mistake in omnipathnav 2025-09-28 22:43:15 -05:00
Carmendar b99899353c Merge branch 'main' into implement_pokemon 2025-09-28 22:39:22 -05:00
Hiroku c3c17a228e Merge branch 'riding-work-hiro' into 'main'
Riding setting and stamina changes

See merge request cable-mc/cobblemon!1880
2025-09-29 02:13:24 +00:00
Paul 41d607ad56 Remember the last camera type used for a mount type and switch to it if the config is enabled 2025-09-29 11:05:41 +10:00
Hiroku 58b3596948 Wait that wasn't meant to still be in there 2025-09-28 11:12:33 +00:00
Paul ed4456d756 API and config and controller options for infinite stamina 2025-09-28 15:47:17 +10:00
violet 608b711833 minor fix to exeggutor's animations 🥚 2025-09-28 00:59:44 -04:00
violet 3adc1b9f30 altered posers for staryu, starmie, and corsola 🫧 2025-09-28 00:35:52 -04:00
violet 478cbc2489 updated models & animations for litwick, lampent, and chandelure 🕯️ 2025-09-27 23:49:26 -04:00
Test 481734e6b1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-09-27 20:44:47 -04:00
Test 636792fa1f rm unused function 2025-09-27 20:44:40 -04:00
Test ad65002b19 fix stat color 2025-09-27 20:43:44 -04:00
Sterrezo 903f3b6d5a Removed an unused sound from sounds.json 2025-09-27 12:15:22 +02:00
Paul 4456743e97 Merge remote-tracking branch 'origin/main' into riding-work-hiro
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/data/CobblemonDataProvider.kt
2025-09-27 18:41:27 +10:00
Paul d0989e5ece Migrated all the other controllers to support the global config 2025-09-27 18:40:57 +10:00
Carmendar 03edb5a385 Merge branch 'main' into implement_pokemon 2025-09-27 02:47:44 -05:00
Paul 180229db61 Merge remote-tracking branch 'origin/main' into riding-work-hiro 2025-09-27 16:18:31 +10:00
Carmendar cf77713860 No more Hydreigon quirks while flying. 2025-09-27 01:08:41 -05:00
Paul b6e10c016e Migrate global ride controller settings to use a different solution 2025-09-27 16:06:13 +10:00
Carmendar 0494193c9b fixed paldean tauros falling too. 2025-09-26 22:50:30 -05:00
Carmendar 7bee34170d removed non-existant quirk from crobat poser & fixed tauros falling in battle. 2025-09-26 22:47:49 -05:00
Paul ce09236dab Added global controller settings for riding, moved jet over to it 2025-09-27 12:39:17 +10:00
Guilherme Pereira 0bb968dd73 add pokémon fullness to pokémon properties 2025-09-26 11:42:58 -03:00
Guilherme Pereira f3d4cb34e0 fix poke puff tooltip and mild multiplier #1711 #1710 2025-09-26 10:41:17 -03:00
Paul 3b6e1bd429 Persist stamina between dismount and mount 2025-09-26 11:24:44 +10:00
Guilherme Pereira 1eb7354fc0 update CHANGELOG.md 2025-09-25 16:49:59 -03:00
Guilherme Pereira 52ad6a3250 fix mochi tooltips #1689 2025-09-25 16:24:15 -03:00
Guilherme Pereira aa57bbbf34 fix glint on enchanted pokémon item models #1696 2025-09-25 16:20:17 -03:00
Guilherme Pereira 26278eeb46 fix regional food items not usable on pokémon #1708 2025-09-25 14:55:41 -03:00
Jerzykv 1a30109f1c Galarian Farfetch'd can no longer fly 2025-09-23 15:03:21 +02:00
Nico Merenq efd4a72287 Translated using Weblate (Russian)
Currently translated at 63.1% (5598 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-21 23:09:39 +00:00
violet 5088497575 MANECTRIC. 2025-09-21 18:55:04 -04:00
Watuneni iteite bba8a12a2a Translated using Weblate (Japanese)
Currently translated at 85.7% (7608 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-21 10:00:32 +00:00
阿鱼 1cdf664dce Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8833 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-09-20 07:30:00 +00:00
Watuneni iteite 2ea5eb2823 Translated using Weblate (Japanese)
Currently translated at 85.7% (7602 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-16 18:48:56 +00:00
Nico Merenq e109b0fc9f Translated using Weblate (Russian)
Currently translated at 63.0% (5595 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-14 14:39:57 +00:00
Watuneni iteite 5de7f96fef Translated using Weblate (Japanese)
Currently translated at 85.6% (7595 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-14 14:39:56 +00:00
Nico Merenq 1f62f447b5 Translated using Weblate (Russian)
Currently translated at 62.8% (5572 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-13 18:04:21 +00:00
Nico Merenq 674e1df96d Translated using Weblate (Russian)
Currently translated at 62.8% (5571 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-11 17:08:21 +00:00
Watuneni iteite a4a2ae6133 Translated using Weblate (Japanese)
Currently translated at 85.6% (7595 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-11 17:08:20 +00:00
Nico Merenq a5c3d2f800 Translated using Weblate (Russian)
Currently translated at 62.5% (5549 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-07 20:08:56 +00:00
Teggy 00d2bbbe42 Translated using Weblate (Spanish)
Currently translated at 85.5% (7586 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-09-07 20:08:55 +00:00
Teggy 40b351a303 Translated using Weblate (Spanish)
Currently translated at 85.5% (7586 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-09-06 12:01:45 +00:00
Not telling you that dc32bd1845 Translated using Weblate (Spanish)
Currently translated at 85.5% (7586 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-09-06 12:01:45 +00:00
Nico Merenq a096485155 Translated using Weblate (Russian)
Currently translated at 62.0% (5508 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-06 11:58:11 +00:00
Teggy f1ae7c4476 Translated using Weblate (Spanish)
Currently translated at 85.4% (7579 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-09-06 11:58:10 +00:00
Not telling you that bcfac2f68a Translated using Weblate (Spanish)
Currently translated at 85.4% (7579 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-09-06 11:58:10 +00:00
Nico Merenq ff1902770c Translated using Weblate (Russian)
Currently translated at 62.0% (5503 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-06 11:52:11 +00:00
Not telling you that ebb01d4fcc Translated using Weblate (Spanish)
Currently translated at 85.3% (7571 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-09-06 11:52:11 +00:00
阿鱼 0b392c66eb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8833 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-09-04 12:47:12 +00:00
Nico Merenq 5733074bd8 Translated using Weblate (Russian)
Currently translated at 61.5% (5460 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-04 12:47:11 +00:00
阿鱼 88ff4e37b8 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8833 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-09-03 03:48:57 +00:00
Nico Merenq 35b7a80501 Translated using Weblate (Russian)
Currently translated at 61.4% (5455 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-09-02 12:29:43 +00:00
Watuneni iteite 91949414cc Translated using Weblate (Japanese)
Currently translated at 85.6% (7595 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-09-02 12:29:42 +00:00
washashu0905 10bfe3b29d Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 96.8% (8593 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-08-30 11:18:38 +00:00
阿鱼 ff88a3c756 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-08-30 11:18:38 +00:00
washashu0905 4d47cb8385 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 96.7% (8582 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-08-30 00:42:40 +00:00
washashu0905 8aba2bc279 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 96.1% (8530 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-08-29 23:50:13 +00:00
Nico Merenq fe91e912d0 Translated using Weblate (Russian)
Currently translated at 59.5% (5284 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-29 13:16:35 +00:00
Alexis Salgueiro 680bc1d205 Translated using Weblate (French)
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-28 20:17:51 +00:00
阿鱼 d0c4bd5a16 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-08-26 20:41:46 +00:00
Watuneni iteite 500069e5d8 Translated using Weblate (Japanese)
Currently translated at 85.2% (7561 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-26 20:41:45 +00:00
Nico Merenq 13ae174c66 Translated using Weblate (Russian)
Currently translated at 58.0% (5148 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-25 21:25:28 +00:00
Nico Merenq 3bf777c2a9 Translated using Weblate (Russian)
Currently translated at 58.0% (5147 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-23 10:45:45 +00:00
Nico Merenq b5174686b4 Translated using Weblate (Russian)
Currently translated at 57.9% (5138 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-22 06:04:58 +00:00
Watuneni iteite 26a7bc29b3 Translated using Weblate (Japanese)
Currently translated at 85.1% (7555 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-22 06:04:57 +00:00
Nico Merenq 05cd37eb38 Translated using Weblate (Russian)
Currently translated at 57.9% (5136 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-20 23:46:22 +00:00
Nico Merenq 3ac3fcbcda Translated using Weblate (Russian)
Currently translated at 57.4% (5092 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-18 18:30:18 +00:00
Weblate 27b3884f27 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-08-16 21:52:57 +00:00
dhi_holo 15e8f46702 Translated using Weblate (English (en_PT))
Currently translated at 24.6% (2189 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/en_PT/
2025-08-16 21:52:53 +00:00
dhi_holo e91b1061d3 Translated using Weblate (English (United Kingdom))
Currently translated at 0.8% (71 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/en_GB/
2025-08-16 21:52:51 +00:00
阿鱼 f042d167d1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-08-14 07:35:19 +00:00
Watuneni iteite eff3bd91d7 Translated using Weblate (Japanese)
Currently translated at 84.9% (7538 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-13 11:19:51 +00:00
Nico Merenq 1391bfee01 Translated using Weblate (Russian)
Currently translated at 56.9% (5054 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-10 10:56:14 +00:00
Watuneni iteite e8b6bee139 Translated using Weblate (Japanese)
Currently translated at 84.9% (7538 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-09 09:35:43 +00:00
Nico Merenq a98bc80005 Translated using Weblate (Russian)
Currently translated at 56.9% (5052 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-08 15:26:11 +00:00
Zack the Ghast 06d25a043c Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.7% (6097 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-08 02:52:08 +00:00
Zack the Ghast 6aa3b8b92f Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.5% (6082 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-08 00:40:47 +00:00
Nico Merenq 7381b47830 Translated using Weblate (Russian)
Currently translated at 56.1% (4981 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-07 13:28:54 +00:00
Watuneni iteite b2a704fa12 Translated using Weblate (Japanese)
Currently translated at 84.8% (7528 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-07 13:28:52 +00:00
Zack the Ghast 41ed476c00 Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.4% (6072 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-07 04:26:31 +00:00
Nico Merenq 44ddf097d6 Translated using Weblate (Russian)
Currently translated at 55.7% (4948 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-06 20:04:57 +00:00
Zack the Ghast cb1386fdb3 Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.2% (6051 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-06 20:04:56 +00:00
Nico Merenq 0dafe79032 Translated using Weblate (Russian)
Currently translated at 55.3% (4911 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-06 14:49:22 +00:00
Nico Merenq 51cd929d1c Translated using Weblate (Russian)
Currently translated at 55.3% (4911 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-06 12:06:36 +00:00
Nico Merenq 5468d5e888 Translated using Weblate (Russian)
Currently translated at 54.6% (4851 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-06 11:23:20 +00:00
Nico Merenq 0174b8bc67 Translated using Weblate (Russian)
Currently translated at 54.5% (4840 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-06 11:18:06 +00:00
Watuneni iteite e3b8fbb973 Translated using Weblate (Japanese)
Currently translated at 84.8% (7527 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-06 11:18:05 +00:00
Nico Merenq 7103df0116 Translated using Weblate (Russian)
Currently translated at 53.5% (4752 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-06 10:25:46 +00:00
Zack the Ghast 42fba85241 Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.2% (6050 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-06 10:25:45 +00:00
Watuneni iteite f9f11c7137 Translated using Weblate (Japanese)
Currently translated at 84.0% (7452 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-06 10:25:45 +00:00
Zack the Ghast a51acead21 Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.1% (6048 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-06 08:53:38 +00:00
Watuneni iteite 7a3ab17e57 Translated using Weblate (Japanese)
Currently translated at 82.0% (7280 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-06 08:53:37 +00:00
Watuneni iteite d4e741c614 Translated using Weblate (Japanese)
Currently translated at 81.7% (7248 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-06 08:11:59 +00:00
Watuneni iteite bee1797ff5 Translated using Weblate (Japanese)
Currently translated at 81.7% (7247 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-06 08:06:41 +00:00
Watuneni iteite 72fa7d42d5 Translated using Weblate (Japanese)
Currently translated at 81.6% (7243 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-06 07:47:36 +00:00
Zack the Ghast 7a4bf4cc5d Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.1% (6046 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-06 01:23:25 +00:00
Zack the Ghast ab66e13c8c Translated using Weblate (Portuguese (Portugal))
Currently translated at 68.0% (6038 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-06 00:45:38 +00:00
Zack the Ghast eaeea493a1 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.8% (6022 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-05 23:49:36 +00:00
Nico Merenq 0bfaedbf6e Translated using Weblate (Russian)
Currently translated at 53.5% (4752 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-05 20:57:37 +00:00
Zack the Ghast 52f9f45608 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.8% (6016 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-05 20:57:36 +00:00
Zack the Ghast dfa9dc1e2b Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.5% (5992 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-05 12:37:13 +00:00
Nico Merenq c8f5538ae8 Translated using Weblate (Russian)
Currently translated at 53.3% (4728 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-05 12:12:59 +00:00
Nico Merenq 5af5a59ff1 Translated using Weblate (Russian)
Currently translated at 52.7% (4679 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-05 10:18:42 +00:00
Zack the Ghast eb37ecbe56 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.5% (5991 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-05 03:22:34 +00:00
Zack the Ghast d7b528aef1 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.4% (5981 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-08-05 02:27:49 +00:00
Nico Merenq 2908ca3a89 Translated using Weblate (Russian)
Currently translated at 52.5% (4660 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 23:50:47 +00:00
Nico Merenq aa04dc077b Translated using Weblate (Russian)
Currently translated at 52.5% (4657 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 21:31:48 +00:00
Nico Merenq c1c064e657 Translated using Weblate (Russian)
Currently translated at 52.4% (4653 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 20:35:53 +00:00
washashu0905 c0a509820f Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 95.8% (8498 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-08-04 20:30:32 +00:00
Nico Merenq aa0b71aad7 Translated using Weblate (Russian)
Currently translated at 52.4% (4651 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 20:30:31 +00:00
Nico Merenq 55c5dfddc4 Translated using Weblate (Russian)
Currently translated at 51.9% (4610 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 16:16:22 +00:00
Nico Merenq b40c69a1d9 Translated using Weblate (Russian)
Currently translated at 51.9% (4610 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 16:15:06 +00:00
Watuneni iteite ca20f432b3 Translated using Weblate (Japanese)
Currently translated at 81.6% (7238 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 16:15:05 +00:00
Watuneni iteite 63fe61b913 Translated using Weblate (Japanese)
Currently translated at 80.9% (7177 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 15:53:50 +00:00
Nico Merenq 7605b526c8 Translated using Weblate (Russian)
Currently translated at 51.9% (4606 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 15:53:34 +00:00
Watuneni iteite 189f39f1c1 Translated using Weblate (Japanese)
Currently translated at 80.9% (7176 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 15:53:33 +00:00
Nico Merenq 8c718069c7 Translated using Weblate (Russian)
Currently translated at 51.7% (4586 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 14:15:27 +00:00
Nico Merenq c2facdf5ce Translated using Weblate (Russian)
Currently translated at 51.1% (4539 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-04 10:23:03 +00:00
Watuneni iteite 0c5dcb26f6 Translated using Weblate (Japanese)
Currently translated at 79.8% (7084 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 10:23:02 +00:00
Watuneni iteite b88634691b Translated using Weblate (Japanese)
Currently translated at 79.8% (7082 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 08:28:46 +00:00
Watuneni iteite df9dcdd622 Translated using Weblate (Japanese)
Currently translated at 79.7% (7070 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 07:51:11 +00:00
Watuneni iteite 15943fae47 Translated using Weblate (Japanese)
Currently translated at 79.6% (7069 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 07:50:58 +00:00
Watuneni iteite 78a71ba252 Translated using Weblate (Japanese)
Currently translated at 79.6% (7064 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 07:46:32 +00:00
Watuneni iteite 7f1acd16b5 Translated using Weblate (Japanese)
Currently translated at 79.5% (7060 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 07:43:04 +00:00
Watuneni iteite be038d2348 Translated using Weblate (Japanese)
Currently translated at 78.9% (7004 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-04 06:54:08 +00:00
阿鱼 b3b11012f4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-08-04 03:55:56 +00:00
Watuneni iteite 095c466b89 Translated using Weblate (Japanese)
Currently translated at 78.8% (6992 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 19:29:01 +00:00
Watuneni iteite 4c3cd6fdc4 Translated using Weblate (Japanese)
Currently translated at 78.2% (6943 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 17:05:25 +00:00
Watuneni iteite 2379b22135 Translated using Weblate (Japanese)
Currently translated at 77.7% (6893 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 16:18:02 +00:00
Watuneni iteite f36fa861da Translated using Weblate (Japanese)
Currently translated at 77.5% (6876 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 16:12:31 +00:00
Watuneni iteite 3b4f9d0fba Translated using Weblate (Japanese)
Currently translated at 77.0% (6838 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 15:47:39 +00:00
Watuneni iteite 42dabbf16a Translated using Weblate (Japanese)
Currently translated at 75.6% (6714 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 14:46:18 +00:00
Watuneni iteite 07abff7583 Translated using Weblate (Japanese)
Currently translated at 75.1% (6665 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-08-03 13:05:07 +00:00
Nico Merenq dbd9bfacc5 Translated using Weblate (Russian)
Currently translated at 50.5% (4486 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-03 11:59:16 +00:00
Nico Merenq 6ed1ea0cad Translated using Weblate (Russian)
Currently translated at 50.5% (4486 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-03 11:33:17 +00:00
Yasito 5384fec57e Translated using Weblate (French)
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 04:33:05 +00:00
Yasito 1868bcf4d7 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 04:33:04 +00:00
Yasito 42059b9931 Translated using Weblate (French)
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 04:02:52 +00:00
Yasito 24890225a2 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 04:02:52 +00:00
Yasito e4e32769dc Translated using Weblate (French)
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:50:45 +00:00
Yasito 3420422a4b Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:50:44 +00:00
Yasito 18564baec7 Translated using Weblate (French)
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:43:40 +00:00
Yasito b0c6d83913 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:43:39 +00:00
Yasito 5016b2b227 Translated using Weblate (French)
Currently translated at 99.8% (8860 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:38:25 +00:00
Yasito 4727321d47 Translated using Weblate (French)
Currently translated at 99.8% (8857 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:37:46 +00:00
Yasito 6e96e92d33 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:37:45 +00:00
Yasito a8c92ce641 Translated using Weblate (French)
Currently translated at 99.8% (8854 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:32:47 +00:00
Yasito 032d2e5c95 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:32:46 +00:00
Yasito ec9d7d9dae Translated using Weblate (French)
Currently translated at 99.8% (8853 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:26:48 +00:00
Yasito 217dab4dea Translated using Weblate (French (Canada))
Currently translated at 100.0% (8870 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:26:47 +00:00
Yasito 452a92daa9 Translated using Weblate (French (Canada))
Currently translated at 99.9% (8862 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:12:08 +00:00
Yasito fb364deff9 Translated using Weblate (French)
Currently translated at 99.5% (8831 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-08-03 03:06:55 +00:00
Yasito ac824ce39c Translated using Weblate (French (Canada))
Currently translated at 99.8% (8859 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-08-03 03:06:54 +00:00
Nico Merenq fa74a1c45a Translated using Weblate (Russian)
Currently translated at 50.5% (4480 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-02 13:19:58 +00:00
Nico Merenq 1cce1d1a44 Translated using Weblate (Russian)
Currently translated at 50.1% (4451 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-08-02 12:39:24 +00:00
Yasito b7f537e34c Translated using Weblate (French)
Currently translated at 99.5% (8830 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-31 04:25:44 +00:00
Yasito 0311a8a4ef Translated using Weblate (French (Canada))
Currently translated at 99.5% (8830 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-31 04:25:43 +00:00
Yasito 14ecc13cb3 Translated using Weblate (French)
Currently translated at 99.5% (8830 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-31 03:53:38 +00:00
Yasito 5baca56d6d Translated using Weblate (French (Canada))
Currently translated at 99.5% (8830 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-31 03:53:37 +00:00
Yasito 91c9692db1 Translated using Weblate (French)
Currently translated at 99.5% (8830 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-31 03:52:50 +00:00
Yasito bb7b1a8dee Translated using Weblate (French (Canada))
Currently translated at 99.5% (8830 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-31 03:52:49 +00:00
Yasito e6322e5fb7 Translated using Weblate (French)
Currently translated at 99.1% (8798 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-31 03:42:06 +00:00
Yasito 3c5f04b52a Translated using Weblate (French (Canada))
Currently translated at 99.4% (8825 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-31 03:42:05 +00:00
Yasito 5d78a5b573 Translated using Weblate (French)
Currently translated at 99.1% (8796 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-31 03:39:37 +00:00
Yasito 4f58615065 Translated using Weblate (French (Canada))
Currently translated at 99.4% (8823 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-31 03:39:36 +00:00
Yasito 32a4161a69 Translated using Weblate (French)
Currently translated at 99.1% (8793 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 16:09:48 +00:00
Yasito c5708145cd Translated using Weblate (French (Canada))
Currently translated at 99.1% (8793 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 16:09:47 +00:00
Kakuno 118f207adb Translated using Weblate (French)
Currently translated at 98.7% (8762 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:59:57 +00:00
Yasito a5826028b3 Translated using Weblate (French)
Currently translated at 98.7% (8762 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:59:57 +00:00
Yasito fa3f6053c3 Translated using Weblate (French (Canada))
Currently translated at 98.7% (8762 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:59:56 +00:00
Kakuno bc60fe58b1 Translated using Weblate (French)
Currently translated at 98.7% (8756 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:51:13 +00:00
Yasito f9a5e9a9e4 Translated using Weblate (French)
Currently translated at 98.7% (8756 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:51:13 +00:00
Yasito 6f6ee6f160 Translated using Weblate (French (Canada))
Currently translated at 98.7% (8755 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:51:12 +00:00
Kakuno 8a3dbd5e4a Translated using Weblate (French)
Currently translated at 98.6% (8754 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:48:18 +00:00
Yasito e052ad2281 Translated using Weblate (French)
Currently translated at 98.6% (8754 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:48:17 +00:00
Yasito 8938ea13a4 Translated using Weblate (French (Canada))
Currently translated at 98.6% (8753 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:48:17 +00:00
Yasito 907aed4c63 Translated using Weblate (French)
Currently translated at 98.6% (8752 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:45:17 +00:00
Kakuno 60798aae03 Translated using Weblate (French)
Currently translated at 98.6% (8752 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:45:16 +00:00
Yasito 6f09957fbf Translated using Weblate (French (Canada))
Currently translated at 98.6% (8751 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:45:16 +00:00
Kakuno 6fc2344473 Translated using Weblate (French)
Currently translated at 98.5% (8741 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:38:53 +00:00
Yasito c82059ae72 Translated using Weblate (French)
Currently translated at 98.5% (8741 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:38:53 +00:00
Yasito a080db690f Translated using Weblate (French (Canada))
Currently translated at 98.5% (8740 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:38:53 +00:00
Kakuno d82849ddd3 Translated using Weblate (French)
Currently translated at 98.5% (8740 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:36:11 +00:00
Yasito 71a3fe6e48 Translated using Weblate (French)
Currently translated at 98.5% (8740 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:36:11 +00:00
Yasito 5e934ac7a6 Translated using Weblate (French (Canada))
Currently translated at 98.5% (8739 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:36:10 +00:00
Natchakot Chuchokjatuporn 6aa5bde424 Translated using Weblate (Thai)
Currently translated at 54.3% (4818 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2025-07-30 03:22:26 +00:00
Kakuno fee7488090 Translated using Weblate (French)
Currently translated at 98.3% (8726 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-30 03:22:25 +00:00
Yasito f5e5e3411e Translated using Weblate (French (Canada))
Currently translated at 98.3% (8725 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-30 03:22:24 +00:00
Natchakot Chuchokjatuporn 818f9365ec Translated using Weblate (Thai)
Currently translated at 52.6% (4669 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2025-07-29 03:34:54 +00:00
Kakuno f81db9df3d Translated using Weblate (French)
Currently translated at 98.3% (8722 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-29 03:34:52 +00:00
Yasito 8162e3a30d Translated using Weblate (French)
Currently translated at 98.3% (8722 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-29 03:34:52 +00:00
Yasito 5a00bbf02d Translated using Weblate (French (Canada))
Currently translated at 98.3% (8722 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-29 03:34:50 +00:00
Natchakot Chuchokjatuporn ff7fff52ec Translated using Weblate (Thai)
Currently translated at 52.0% (4620 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/th/
2025-07-29 03:23:48 +00:00
Kakuno 087fab4065 Translated using Weblate (French)
Currently translated at 98.2% (8719 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-29 03:23:48 +00:00
Yasito bed2897950 Translated using Weblate (French)
Currently translated at 98.2% (8719 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-29 03:23:47 +00:00
Yasito d51f0711b7 Translated using Weblate (French (Canada))
Currently translated at 98.2% (8719 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-29 03:23:46 +00:00
Felipe Bermudes Ormeño 728860332d Translated using Weblate (Spanish (Mexico))
Currently translated at 26.9% (2390 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-07-29 03:23:45 +00:00
Felipe Bermudes Ormeño fe0ca14b3b Translated using Weblate (Spanish (Mexico))
Currently translated at 26.2% (2330 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-07-28 23:07:55 +00:00
Yasito 7e57c3c862 Translated using Weblate (French)
Currently translated at 96.7% (8586 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-28 17:41:18 +00:00
Yasito 0f4fdfcedd Translated using Weblate (French (Canada))
Currently translated at 96.7% (8586 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-28 17:41:17 +00:00
Felipe Bermudes Ormeño 1cb77f35b5 Translated using Weblate (Spanish (Mexico))
Currently translated at 25.3% (2247 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-07-28 17:41:16 +00:00
阿鱼 9ac23be59b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-28 01:58:42 +00:00
Kakuno e469409a22 Translated using Weblate (French)
Currently translated at 96.6% (8572 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-28 01:58:41 +00:00
Yasito 28db8e98d7 Translated using Weblate (French)
Currently translated at 96.6% (8572 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-28 01:58:41 +00:00
Yasito 08bf3d4f8f Translated using Weblate (French (Canada))
Currently translated at 96.6% (8572 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-28 01:58:39 +00:00
Felipe Bermudes Ormeño 88380bfb76 Translated using Weblate (Spanish (Mexico))
Currently translated at 25.2% (2240 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-07-28 01:58:38 +00:00
Kakuno 83d7cbbefa Translated using Weblate (French)
Currently translated at 96.0% (8524 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-27 23:23:04 +00:00
Yasito 426d7c8e5e Translated using Weblate (French)
Currently translated at 96.0% (8524 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-27 23:23:04 +00:00
Yasito 602d88db5e Translated using Weblate (French (Canada))
Currently translated at 95.8% (8506 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-27 23:23:03 +00:00
Felipe Bermudes Ormeño 751d3be872 Translated using Weblate (Spanish (Mexico))
Currently translated at 25.0% (2220 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-07-27 23:23:00 +00:00
Kakuno 358a62d5b1 Translated using Weblate (French)
Currently translated at 96.0% (8521 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-27 22:45:12 +00:00
Yasito 409814823b Translated using Weblate (French (Canada))
Currently translated at 95.7% (8490 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-27 22:45:11 +00:00
Kakuno 5d8f45b058 Translated using Weblate (French)
Currently translated at 96.0% (8520 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-27 22:42:03 +00:00
Yasito 3001e8bf84 Translated using Weblate (French (Canada))
Currently translated at 95.6% (8488 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-27 22:42:02 +00:00
阿鱼 80de268987 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-27 22:40:38 +00:00
Kakuno b08004b6c6 Translated using Weblate (French)
Currently translated at 96.0% (8519 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-27 22:40:37 +00:00
Yasito 2783a52495 Translated using Weblate (French)
Currently translated at 96.0% (8519 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-27 22:40:36 +00:00
Yasito 3ae3f0db95 Translated using Weblate (French (Canada))
Currently translated at 95.6% (8486 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-07-27 22:40:35 +00:00
阿鱼 a15f026739 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.5% (8832 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-27 18:38:05 +00:00
阿鱼 bc8ed8bb38 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.9% (8776 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-27 16:54:12 +00:00
阿鱼 efa246272b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.7% (8758 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-27 05:55:51 +00:00
阿鱼 e29d84a71a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.1% (8617 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-26 18:52:35 +00:00
阿鱼 6c671b5e08 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.9% (8598 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-25 22:35:43 +00:00
Weblate 3ffd9ecc28 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-07-25 07:41:41 +00:00
阿鱼 281131f5b3 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.3% (8543 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-25 07:41:37 +00:00
Nico Merenq 3c67cd2a59 Translated using Weblate (Russian)
Currently translated at 49.7% (4411 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-07-25 07:41:36 +00:00
阿鱼 74f5c69bb5 Translated using Weblate (French)
Currently translated at 95.9% (8513 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-25 07:41:35 +00:00
Teggy 8f82e1d960 Translated using Weblate (Spanish)
Currently translated at 85.3% (7567 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-25 07:41:34 +00:00
Nico Merenq c5497cfb2b Translated using Weblate (Russian)
Currently translated at 49.6% (4406 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-07-22 22:10:58 +00:00
Nico Merenq 94b6b3b948 Translated using Weblate (Russian)
Currently translated at 49.6% (4405 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-07-22 21:58:42 +00:00
Kakuno 8855c5ad7f Translated using Weblate (French)
Currently translated at 95.9% (8513 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 15:14:45 +00:00
Alexis Salgueiro 5015a0a56c Translated using Weblate (French)
Currently translated at 95.9% (8513 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 15:14:44 +00:00
Kakuno ec51fc0701 Translated using Weblate (French)
Currently translated at 95.9% (8512 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:33:22 +00:00
Alexis Salgueiro 13287e6f76 Translated using Weblate (French)
Currently translated at 95.9% (8512 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:33:22 +00:00
Kakuno a65dfcd3cd Translated using Weblate (French)
Currently translated at 95.9% (8509 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:28:56 +00:00
Kakuno 18183dd649 Translated using Weblate (French)
Currently translated at 95.9% (8508 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:26:11 +00:00
Alexis Salgueiro 40c1f074bb Translated using Weblate (French)
Currently translated at 95.9% (8508 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:26:10 +00:00
Kakuno 5d1219e467 Translated using Weblate (French)
Currently translated at 95.6% (8482 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:18:30 +00:00
Kakuno 568773f1a8 Translated using Weblate (French)
Currently translated at 95.6% (8481 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:18:08 +00:00
Alexis Salgueiro f0c3cde213 Translated using Weblate (French)
Currently translated at 95.6% (8481 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-07-22 14:18:08 +00:00
Tobias (Targ) def5d09903 Translated using Weblate (German)
Currently translated at 58.8% (5218 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-07-18 13:37:42 +00:00
Watuneni iteite ad5e2ddc41 Translated using Weblate (Japanese)
Currently translated at 75.0% (6661 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-16 08:59:20 +00:00
Teggy 2d2f92c7a7 Translated using Weblate (Spanish)
Currently translated at 84.2% (7470 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-15 18:19:05 +00:00
Watuneni iteite 2bd4d1fb08 Translated using Weblate (Japanese)
Currently translated at 74.0% (6565 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-13 18:01:49 +00:00
Teggy 4c342c2047 Translated using Weblate (Spanish)
Currently translated at 83.1% (7373 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-13 18:01:48 +00:00
Watuneni iteite 24cee748d5 Translated using Weblate (Japanese)
Currently translated at 73.8% (6548 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-10 18:47:55 +00:00
Teggy fbec6f03e7 Translated using Weblate (Spanish)
Currently translated at 81.1% (7199 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-10 18:47:52 +00:00
Teggy 8ab0288ab2 Translated using Weblate (Spanish)
Currently translated at 79.7% (7072 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-10 06:04:53 +00:00
Nico Merenq cc426a5ca9 Translated using Weblate (Russian)
Currently translated at 49.6% (4403 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-07-08 22:17:00 +00:00
Teggy e4f04b605a Translated using Weblate (Spanish)
Currently translated at 79.1% (7025 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-08 22:16:58 +00:00
Teggy 48441b1232 Translated using Weblate (Spanish)
Currently translated at 76.0% (6748 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-06 09:38:57 +00:00
Watuneni iteite 589d3614b8 Translated using Weblate (Japanese)
Currently translated at 68.7% (6099 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-05 04:12:04 +00:00
Teggy fe386095de Translated using Weblate (Spanish)
Currently translated at 75.3% (6687 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-04 22:04:28 +00:00
Watuneni iteite 5640177c99 Translated using Weblate (Japanese)
Currently translated at 68.7% (6097 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-04 11:45:00 +00:00
Zack the Ghast ff8c8b1bfa Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.3% (5973 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-07-04 05:53:12 +00:00
Watuneni iteite 4bccd9b5aa Translated using Weblate (Japanese)
Currently translated at 64.2% (5702 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-04 05:53:11 +00:00
阿鱼 8c1c5ac957 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.8% (8498 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-03 05:30:56 +00:00
Watuneni iteite a20ec4d1c5 Translated using Weblate (Japanese)
Currently translated at 64.1% (5694 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-03 05:30:55 +00:00
Teggy 12b4e58dea Translated using Weblate (Spanish)
Currently translated at 75.1% (6669 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-03 05:30:53 +00:00
Zack the Ghast 940ec82182 Translated using Weblate (Portuguese (Portugal))
Currently translated at 67.1% (5952 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-07-02 02:26:55 +00:00
Kyo 67c01ce5f2 Translated using Weblate (Vietnamese)
Currently translated at 65.8% (5842 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-07-01 12:38:56 +00:00
washashu0905 e603325eef Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 94.6% (8398 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-07-01 12:38:54 +00:00
阿鱼 afd09e93eb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.7% (8497 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-07-01 12:38:53 +00:00
Zack the Ghast 92775a4b8a Translated using Weblate (Portuguese (Portugal))
Currently translated at 66.2% (5877 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-07-01 12:38:52 +00:00
Watuneni iteite 6a2668171e Translated using Weblate (Japanese)
Currently translated at 63.2% (5607 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-07-01 12:38:50 +00:00
Teggy 5b7dc9f8f4 Translated using Weblate (Spanish)
Currently translated at 74.2% (6583 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-07-01 12:38:47 +00:00
washashu0905 75dc76020f Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 92.5% (8209 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-29 06:11:55 +00:00
阿鱼 56289ce5bf Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.7% (8496 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-29 06:11:53 +00:00
Zack the Ghast e4ec7b0ae7 Translated using Weblate (Portuguese (Portugal))
Currently translated at 60.7% (5387 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-29 06:11:52 +00:00
Anonymous f38ef0b6b9 Translated using Weblate (Vietnamese)
Currently translated at 63.0% (5592 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-06-29 01:50:06 +00:00
阿鱼 d5bb3e2d97 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.3% (8458 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-29 01:50:04 +00:00
Zack the Ghast 66f6555711 Translated using Weblate (Portuguese (Portugal))
Currently translated at 60.4% (5362 of 8870 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-29 01:50:00 +00:00
Zack the Ghast 472ca9c748 Translated using Weblate (Portuguese (Portugal))
Currently translated at 63.4% (5398 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-29 00:30:29 +00:00
阿鱼 054e4dffdc Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.2% (8358 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-29 00:30:29 +00:00
202 changed files with 23939 additions and 11706 deletions

No files matched your search

+7
View File
@@ -2,6 +2,7 @@
## [1.7.0 (Month xth, 2025)](#1-7-0)
### Additions
- Added `/npcdelete` uuid parameter support and usuable to console
- Added `/spectateBattle <player>` command to spectate battles without having to manually walk up to the target.
- Added an in-game configuration screen, allowing all settings from `main.json` to be edited directly in-game.
- Added `/cobblemonconfig reload` command to reload `main.json` configuration. **Note:** Some settings require a server restart to take effect; use this command cautiously.
@@ -292,6 +293,7 @@
- Tauros - Paldea Blaze
- Tauros - Paldea Combat
- Dewgong
- Exeggutor - Kanto
### Model updates for the following Pokémon
- Cleffa
@@ -402,6 +404,9 @@
- Revavroom
- Nickit
- Thievul
- Litwick
- Lampent
- Chandelure
### Changes
- Changed pokemon caught and seen count to update based on the current pokedex being looked
@@ -466,6 +471,7 @@
- Updated `HatchEggEvent.Post` to include the Pokemon that hatched.
- Roseli Berry Trees now naturally generate in their preferred biomes.
- Refactored dynamic lights compat to be more future proof. The dynamic light support is only tested with LambDynamicLights, on NeoForged use that mod in combination with Sinytra Connector
- Shulker Boxes and Traveler's Backpacks can no longer be held by Pokémon. Thanks Monocle ;) You could re-enable this with a datapack but you'd be crazy.
### Fixes
- Fixed game crashing when removing national pokedex using datapacks
@@ -549,6 +555,7 @@
- Fixed busted abilities and moves in Pokémon data due to removed datapacks etc. causing storage corruption. It now just rerolls their ability / uses Tackle.
- Fixed singular Pokémon corruption causing entire storage corruption. Storages will now skip corrupted Pokémon and print an error to console.
- Fixed species additions not being able to properly mark a species as implemented.
- Fixed Pokémon item models not showing a glint when enchanted.
### Developer
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
@@ -10,8 +10,7 @@ package com.cobblemon.mod.common.mixin.client.snapshots;
import com.cobblemon.mod.common.CobblemonBuildDetails;
import com.cobblemon.mod.common.client.gui.snapshots.SnapshotWarningScreen;
import com.cobblemon.mod.common.client.snapshots.SnapshotAcknowledgementData;
import com.cobblemon.mod.common.client.snapshots.SnapshotAcknowledgementReader;
import com.cobblemon.mod.common.client.persisted.ClientPersistedData;
import kotlin.Unit;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
@@ -42,7 +41,7 @@ public final class SnapshotWarningMixin {
return Unit.INSTANCE;
}
SnapshotAcknowledgementReader.INSTANCE.write(new SnapshotAcknowledgementData(CobblemonBuildDetails.VERSION, dsa));
ClientPersistedData.INSTANCE.writeSnapshotsData(new ClientPersistedData.SnapshotAcknowledgementData(CobblemonBuildDetails.VERSION, dsa));
runnable.run();
return Unit.INSTANCE;
@@ -54,7 +53,7 @@ public final class SnapshotWarningMixin {
@Unique
@SuppressWarnings("ResultOfMethodCallIgnored")
private boolean cobblemon$isAcknowledged() {
SnapshotAcknowledgementData data = SnapshotAcknowledgementReader.INSTANCE.read();
ClientPersistedData.SnapshotAcknowledgementData data = ClientPersistedData.INSTANCE.readSnapshotsData();
if (data == null) {
return false;
}
@@ -213,7 +213,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACCHARINE_SIGN = this.create("saccharine_sign", CobblemonSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_SIGN), SACCHARINE_WOOD_TYPE))
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
@@ -39,6 +39,7 @@ object CobblemonMechanics : DataRegistry {
var potions = PotionsMechanic()
override fun sync(player: ServerPlayer) {}
override fun reload(manager: ResourceManager) {
remedies = loadMechanic(manager, "remedies", RemediesMechanic::class.java)
berries = loadMechanic(manager, "berries", BerriesMechanic::class.java)
@@ -20,6 +20,7 @@ import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandl
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
import com.cobblemon.mod.common.client.net.cooking.ToggleCookingPotLidHandler
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
import com.cobblemon.mod.common.client.net.data.RideSettingsSyncHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
import com.cobblemon.mod.common.client.net.effect.PokeSnackBlockParticlesHandler
@@ -311,6 +312,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(MarksPotentialUpdatePacket.ID, MarksPotentialUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(RideStaminaUpdatePacket.ID, RideStaminaUpdatePacket::decode, PokemonUpdatePacketHandler()))
// Evolution start
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
@@ -405,6 +407,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(CosmeticItemAssignmentSyncPacket.ID, CosmeticItemAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(RideSettingsSyncPacket.ID, RideSettingsSyncPacket::decode, RideSettingsSyncHandler))
// Effects
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
@@ -0,0 +1,106 @@
/*
* 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
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.data.DataRegistry
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.BirdSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.GliderSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.HelicopterSettings
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.land.HorseSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.BoatSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.BurstSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.DolphinSettings
import com.cobblemon.mod.common.net.messages.client.data.RideSettingsSyncPacket
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.adapters.FloatNumberRangeAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.GsonBuilder
import net.minecraft.advancements.critereon.MinMaxBounds
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.server.packs.resources.ResourceManager
object CobblemonRideSettings : DataRegistry {
override val id: ResourceLocation = cobblemonResource("ride_settings")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<CobblemonRideSettings>()
val gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(MinMaxBounds.Doubles::class.java, FloatNumberRangeAdapter)
.create()
var bird = BirdSettings()
var glider = GliderSettings()
var helicopter = HelicopterSettings()
var hover = HoverSettings()
var jet = JetSettings()
var rocket = RocketSettings()
var horse = HorseSettings()
var minekart = MinekartSettings()
var vehicle = VehicleSettings()
var boat = BoatSettings()
var burst = BurstSettings()
var dolphin = DolphinSettings()
override fun sync(player: ServerPlayer) {
player.sendPacket(
RideSettingsSyncPacket(
bird = bird,
glider = glider,
helicopter = helicopter,
hover = hover,
jet = jet,
rocket = rocket,
horse = horse,
minekart = minekart,
vehicle = vehicle,
boat = boat,
burst = burst,
dolphin = dolphin
)
)
}
override fun reload(manager: ResourceManager) {
bird = loadStyle(manager, "bird", BirdSettings::class.java)
glider = loadStyle(manager, "glider", GliderSettings::class.java)
helicopter = loadStyle(manager, "helicopter", HelicopterSettings::class.java)
hover = loadStyle(manager, "hover", HoverSettings::class.java)
jet = loadStyle(manager, "jet", JetSettings::class.java)
rocket = loadStyle(manager, "rocket", RocketSettings::class.java)
horse = loadStyle(manager, "horse", HorseSettings::class.java)
minekart = loadStyle(manager, "minekart", MinekartSettings::class.java)
vehicle = loadStyle(manager, "vehicle", VehicleSettings::class.java)
boat = loadStyle(manager, "boat", BoatSettings::class.java)
burst = loadStyle(manager, "burst", BurstSettings::class.java)
dolphin = loadStyle(manager, "dolphin", DolphinSettings::class.java)
}
private fun <T : RidingBehaviourSettings> loadStyle(manager: ResourceManager, name: String, clazz: Class<T>): T {
manager.getResourceOrThrow(cobblemonResource("ride_settings/$name.json")).open().use {
return gson.fromJson(it.reader(), clazz)
}
}
}
@@ -31,8 +31,10 @@ import net.minecraft.world.entity.ai.behavior.BlockPosTracker
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.level.material.Fluids
import net.minecraft.world.level.pathfinder.PathType
import net.minecraft.world.phys.Vec3
import kotlin.math.ceil
class WaterWanderTaskConfig : SingleTaskConfig {
val condition = booleanVariable(WANDER, "water_wanders", true).asExpressible()
@@ -100,6 +102,33 @@ class WaterWanderTaskConfig : SingleTaskConfig {
return@Trigger false
}
// Move target pos down so that we don't move out of water too much
val requiredDepth = ceil(0.5 + entity.eyeHeight)
// Get the current depth of the block
var depth = 1
var testPos = pos.above()
var blockState = entity.level().getBlockState(testPos)
while (blockState.fluidState.type == Fluids.WATER) {
depth++
testPos = testPos!!.above()
blockState = entity.level().getBlockState(testPos)
}
if (depth < requiredDepth) {
// Iterate down until we reach the desired min depth or we reach a non water block
pos = pos.below()
blockState = entity.level().getBlockState(pos)
while (blockState.fluidState.type == Fluids.WATER && depth < requiredDepth) {
depth ++
pos = pos!!.below()
blockState = entity.level().getBlockState(pos)
}
}
if (depth < requiredDepth) {
return@Trigger false
}
walkTarget.set(
CobblemonWalkTarget(
pos = pos,
@@ -9,13 +9,11 @@
package com.cobblemon.mod.common.api.cooking
import com.cobblemon.mod.common.CobblemonItemComponents
import com.cobblemon.mod.common.item.PokePuffItem
import com.cobblemon.mod.common.item.PokePuffItem.Companion.DISLIKED_FLAVOR_MULTIPLIER
import com.cobblemon.mod.common.item.PokePuffItem.Companion.LIKED_FLAVOR_MULTIPLIER
import com.cobblemon.mod.common.pokemon.Nature
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.world.item.ItemStack
object PokePuffUtils {
@@ -25,11 +23,12 @@ object PokePuffUtils {
val (baseFriendship) = calculateBaseFriendship(stack)
return when {
dominantFlavour == nature.favouriteFlavour -> (baseFriendship / LIKED_FLAVOR_MULTIPLIER).toInt()
dominantFlavour == Flavour.MILD && isNeutralNature -> (baseFriendship / 2.0).coerceAtLeast(1.0).toInt()
else -> (-baseFriendship / DISLIKED_FLAVOR_MULTIPLIER).toInt()
}
val multiplier = if (
dominantFlavour == nature.favouriteFlavour ||
(dominantFlavour == Flavour.MILD && isNeutralNature)
) LIKED_FLAVOR_MULTIPLIER else -DISLIKED_FLAVOR_MULTIPLIER
return (baseFriendship / multiplier).toInt()
}
fun calculateBaseFriendship(stack: ItemStack): Pair<Double, Double> {
@@ -77,8 +76,8 @@ object PokePuffUtils {
Flavour.SPICY -> "attack"
Flavour.DRY -> "special_attack"
Flavour.SWEET -> "speed"
Flavour.BITTER -> "special_defense"
Flavour.SOUR -> "defense"
Flavour.BITTER -> "special_defence"
Flavour.SOUR -> "defence"
Flavour.MILD -> "neutral"
}
}
@@ -152,6 +152,9 @@ object CobblemonEvents {
@JvmField
val RIDE_EVENT_PRE = CancelableObservable<RidePokemonEvent.Pre>()
@JvmField
val RIDE_EVENT_APPLY_STAMINA = EventObservable<RidePokemonEvent.ApplyStamina>()
@JvmField
val RIDE_EVENT_POST = EventObservable<RidePokemonEvent.Post>()
@@ -8,9 +8,7 @@
package com.cobblemon.mod.common.api.events.pokemon
import com.cobblemon.mod.common.util.server
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
@@ -49,4 +47,36 @@ interface RidePokemonEvent {
"pokemon" to pokemon.struct
)
}
/**
* Event published when stamina is being applied. At this point you can modify the stamina that will get used on the
* mount or you can make the stamina infinite. Handy hey.
*/
class ApplyStamina(
override val player: ServerPlayer,
override val pokemon: PokemonEntity,
var rideStamina: Float
) : RidePokemonEvent {
val context = mutableMapOf(
"player" to player.asMoLangValue(),
"pokemon" to pokemon.struct,
"ride_stamina" to DoubleValue(rideStamina)
)
val functions = moLangFunctionMap(
"set_ride_stamina" to { params ->
rideStamina = params.getDouble(0).toFloat().coerceIn(0F, 1F)
DoubleValue.ONE
},
"set_infinite_stamina" to { _ ->
rideStamina = -1F
DoubleValue.ONE
},
)
fun setInfiniteStamina() {
rideStamina = -1F
}
fun isInfiniteStamina() = rideStamina == -1F
}
}
@@ -131,6 +131,7 @@ open class PokemonProperties {
props.species = parseSpeciesIdentifier(keyPairs)
props.form = parseForm(keyPairs)
props.friendship = parseIntProperty(keyPairs, listOf("friendship"))?.coerceIn(0, Cobblemon.config.maxPokemonFriendship)
props.fullness = parseIntProperty(keyPairs, listOf("fullness"))
props.pokeball = parseIdentifierOfRegistry(keyPairs, listOf("pokeball")) { identifier -> PokeBalls.getPokeBall(identifier)?.name?.toString() }
props.nature = parseIdentifierOfRegistry(keyPairs, listOf("nature")) { identifier -> Natures.getNature(identifier)?.name?.toString() }
props.ability = parseStringOfRegistry(keyPairs, listOf("ability")) { Abilities.get(it)?.name }
@@ -326,6 +327,7 @@ open class PokemonProperties {
var gender: Gender? = null
var level: Int? = null
var friendship: Int? = null
var fullness: Int? = null
var pokeball: String? = null
var nature: String? = null
var ability: String? = null
@@ -397,6 +399,7 @@ open class PokemonProperties {
pokemon.setFriendship(pokemon.form.baseFriendship)
}
}
fullness?.let { pokemon.currentFullness = it }
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemon.caughtBall = pokeball } }
nature?.let { Natures.getNature(it.asIdentifierDefaultingNamespace())?.let { nature -> pokemon.nature = nature } }
customProperties.forEach { it.apply(pokemon) }
@@ -504,6 +507,7 @@ open class PokemonProperties {
nickname?.takeIf { it.string != pokemon.nickname?.string }?.let { return false }
form?.takeIf { !it.equals(pokemon.form.name, true) }?.let { return false }
friendship?.takeIf { it != pokemon.friendship }?.let { return false }
fullness?.takeIf { it != pokemon.currentFullness }?.let { return false }
pokeball?.takeIf { it != pokemon.caughtBall.name.toString() }?.let { return false }
nature?.takeIf { it != pokemon.nature.name.toString() }?.let { return false }
ability?.takeIf { it != pokemon.ability.name }?.let { return false }
@@ -588,6 +592,7 @@ open class PokemonProperties {
originalTrainer?.takeIf { it != properties.originalTrainer }?.let{ return false }
originalTrainerType?.takeIf { it != properties.originalTrainerType }?.let{ return false }
moves?.takeIf { it.any { move -> properties.moves?.none { it == move } == true } }?.let { return false }
fullness?.takeIf { it != properties.fullness }?.let { return false }
return true
}
@@ -636,6 +641,7 @@ open class PokemonProperties {
nickname?.let { nbt.putString(DataKeys.POKEMON_NICKNAME, Component.Serializer.toJson(it, registryLookup)) }
form?.let { nbt.putString(DataKeys.POKEMON_FORM_ID, it) }
friendship?.let { nbt.putInt(DataKeys.POKEMON_FRIENDSHIP, it) }
fullness?.let { nbt.putInt(DataKeys.POKEMON_FULLNESS, it) }
pokeball?.let { nbt.putString(DataKeys.POKEMON_CAUGHT_BALL, it) }
nature?.let { nbt.putString(DataKeys.POKEMON_NATURE, it) }
ability?.let { nbt.putString(DataKeys.POKEMON_ABILITY, it) }
@@ -667,6 +673,7 @@ open class PokemonProperties {
nickname = if (tag.contains(DataKeys.POKEMON_NICKNAME)) Component.Serializer.fromJson(tag.getString(DataKeys.POKEMON_NICKNAME), registryLookup) else null
form = if (tag.contains(DataKeys.POKEMON_FORM_ID)) tag.getString(DataKeys.POKEMON_FORM_ID) else null
friendship = if (tag.contains(DataKeys.POKEMON_FRIENDSHIP)) tag.getInt(DataKeys.POKEMON_FRIENDSHIP) else null
fullness = if (tag.contains(DataKeys.POKEMON_FULLNESS)) tag.getInt(DataKeys.POKEMON_FULLNESS) else null
pokeball = if (tag.contains(DataKeys.POKEMON_CAUGHT_BALL)) tag.getString(DataKeys.POKEMON_CAUGHT_BALL) else null
nature = if (tag.contains(DataKeys.POKEMON_NATURE)) tag.getString(DataKeys.POKEMON_NATURE) else null
ability = if (tag.contains(DataKeys.POKEMON_ABILITY)) tag.getString(DataKeys.POKEMON_ABILITY) else null
@@ -700,6 +707,7 @@ open class PokemonProperties {
//nickname?.let { json.addProperty(DataKeys.POKEMON_NICKNAME, Text.Serialization.toJsonString(it)) }
form?.let { json.addProperty(DataKeys.POKEMON_FORM_ID, it) }
friendship?.let { json.addProperty(DataKeys.POKEMON_FRIENDSHIP, it) }
fullness?.let {json.addProperty(DataKeys.POKEMON_FULLNESS, it)}
pokeball?.let { json.addProperty(DataKeys.POKEMON_CAUGHT_BALL, it) }
nature?.let { json.addProperty(DataKeys.POKEMON_NATURE, it) }
ability?.let { json.addProperty(DataKeys.POKEMON_ABILITY, it) }
@@ -732,6 +740,7 @@ open class PokemonProperties {
//nickname = json.get(DataKeys.POKEMON_NICKNAME)?.asString?.let { Text.Serialization.fromJson(it) }
form = json.get(DataKeys.POKEMON_FORM_ID)?.asString
friendship = json.get(DataKeys.POKEMON_FRIENDSHIP)?.asInt
fullness = json.get(DataKeys.POKEMON_FULLNESS)?.asInt
pokeball = json.get(DataKeys.POKEMON_CAUGHT_BALL)?.asString
nature = json.get(DataKeys.POKEMON_NATURE)?.asString
ability = json.get(DataKeys.POKEMON_ABILITY)?.asString
@@ -763,6 +772,7 @@ open class PokemonProperties {
shiny?.let { pieces.add("shiny=$it") }
gender?.let { pieces.add("gender=$it")}
friendship?.let { pieces.add("friendship=$it") }
fullness?.let {pieces.add("fullness=$it")}
pokeball?.let { pieces.add("pokeball=$it") }
nature?.let { pieces.add("nature=$it") }
ability?.let { pieces.add("ability=$it") }
@@ -9,10 +9,7 @@
package com.cobblemon.mod.common.api.riding
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.api.riding.stats.RidingStatDefinition
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.adapters.RidingBehaviourSettingsAdapter
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -32,10 +29,10 @@ class RidingProperties(
{ buffer.readEnumConstant(RidingStyle::class.java) },
{
val key = buffer.readResourceLocation()
val settings = RidingBehaviourSettingsAdapter.types[key]?.getConstructor()?.newInstance()
val behaviour = RidingBehaviourSettingsAdapter.types[key]?.getConstructor()?.newInstance()
?: error("Unknown controller key: $key")
settings.decode(buffer)
settings
behaviour.decode(buffer)
behaviour
}
)
}
@@ -51,7 +48,10 @@ class RidingProperties(
buffer.writeMap(
v,
{ _, style -> buffer.writeEnumConstant(style) },
{ _, behaviour -> behaviour.encode(buffer) }
{ _, behaviour ->
buffer.writeResourceLocation(behaviour.key)
behaviour.encode(buffer)
}
)
}
}
@@ -19,6 +19,9 @@ import net.minecraft.resources.ResourceLocation
* Typically this will be initialized for each pokemon form during deserialization
* to determine how they should ride.
*
* These also exist in a datapacked folder, ride_settings, which are used for the fallback
* values if non-stat settings are omitted in the pokemon form JSON.
*
* @author landonjw
*/
interface RidingBehaviourSettings: Encodable, Decodable {
@@ -27,8 +30,6 @@ interface RidingBehaviourSettings: Encodable, Decodable {
fun calculate(stat: RidingStat, boostAmount: Float): Float {
val range = stats[stat] ?: return 0F
return range.first + boostAmount
return (range.first + boostAmount).coerceAtMost(range.endInclusive.toFloat())
}
fun hasStat(stat: RidingStat) = stats.containsKey(stat)
}
@@ -18,7 +18,7 @@ import net.minecraft.world.phys.Vec3
* This is intended to contain mutable state that is passed between the client and server
* or temporary state that is used during the riding process.
*
* This will be destroyed when the a user dismounts the Pokemon.
* This will be destroyed when the main rider dismounts the Pokemon.
*
* @author landonjw
*/
@@ -8,13 +8,17 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.DoubleJump
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.client.MountedCameraTypeHandler
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.FluidTags
import net.minecraft.world.entity.LivingEntity
import kotlin.collections.get
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.player.Player
/**
* Small wrapper around a RidingBehaviour to provide sane defaults in the event that the behaviour is not active.
@@ -50,6 +54,14 @@ class RidingController(
val newState = RidingBehaviours.get(behaviourSettings.key).createDefaultState(behaviourSettings)
context?.let { newState.stamina.set(it.state.stamina.get(), forced = true) }
context?.let { newState.rideVelocity.set(it.state.rideVelocity.get(), forced = true) }
val previousKey = context?.behaviour
val newKey = behaviourSettings.key
for (passenger in entity.passengers) {
if (passenger is Player && passenger !is ServerPlayer) {
MountedCameraTypeHandler.handleTransition(previousKey ?: continue, newKey)
}
}
context = ActiveRidingContext(behaviourSettings.key, behaviourSettings, newState, newTransition)
lastTransitionAge = entity.ticksLived
} else {
@@ -98,7 +110,11 @@ class RidingController(
private fun canTransitionToLand(): Boolean {
if (entity.isInLiquid || entity.isUnderWater) return false
return entity.onGround()
if (entity.onGround()) return true
val y = 0.1
val nearGround = !entity.level().noCollision(entity, entity.boundingBox.move(0.0, -y, 0.0))
return nearGround
}
private fun canTransitionToLiquid(): Boolean {
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.air
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.Cobblemon
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.riding.RidingStyle
@@ -49,6 +50,9 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
val poseProvider = PoseProvider<BirdSettings, BirdState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.2 })
val globalBird: BirdSettings
get() = CobblemonRideSettings.bird
override fun isActive(settings: BirdSettings, state: BirdState, vehicle: PokemonEntity): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
//Need to check other fluids
@@ -118,7 +122,7 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
// Grab the boost time in seconds and convert to ticks. Then calculate the drain rate as inversely
// proportional to the number of ticks of boost thus making a full boost take x ticks
// in short: "Stamina drains slower at higher values and also replenishes slower"
val totalStam = vehicle.runtime.resolveDouble(settings.staminaExpr) * 20.0f
val totalStam = vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalBird.staminaExpr!!) * 20.0f
val stamDrainRate = (1.0f / totalStam).toFloat()
val newStam = if (driver.zza > 0.0) max(0.0f,stam - stamDrainRate)
@@ -174,9 +178,9 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
*/
fun calculateRideSpaceVel(settings: BirdSettings, state: BirdState, vehicle: PokemonEntity, driver: Player) {
// retrieve stats
val topSpeed = (vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0)
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr) * 20.0)
val glideTopSpeed = topSpeed * vehicle.runtime.resolveDouble(settings.glidespeedExpr)
val topSpeed = (vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBird.speedExpr!!) / 20.0)
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalBird.accelerationExpr!!) * 20.0)
val glideTopSpeed = topSpeed * vehicle.runtime.resolveDouble(settings.glideSpeedExpr ?: globalBird.glideSpeedExpr!!)
var glideSpeedChange = 0.0
var activeInput = false
@@ -285,8 +289,8 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
if (driver !is OrientationControllable) return Vec3.ZERO
val controller = (driver as OrientationControllable).orientationController
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalBird.handlingExpr!!)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBird.speedExpr!!) / 20.0
val yawDeltaDeg = deltaTime * handling * sin(Math.toRadians(controller.roll.toDouble())) //* sin(Math.toRadians(controller.roll.toDouble())).sign
val trueYawDelt = yawDeltaDeg * abs(cos(Math.toRadians(controller.pitch.toDouble())))// * sqrt(RidingBehaviour.scaleToRange(state.rideVelocity.get().length(), 0.0, topSpeed))
@@ -313,7 +317,7 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
) {
// Calculate correcting roll force.
// Mult by cos(pitch) to ensure that it doesn't roll correct at when diving or climbing
val rollCorrectionTimer = vehicle.runtime.resolveDouble(settings.timeToRollCorrect)
val rollCorrectionTimer = vehicle.runtime.resolveDouble(settings.timeToRollCorrect ?: globalBird.timeToRollCorrect!!)
val maxRollCorrectionRate = if (state.rideVelocity.get().length() < 0.1) 15.0f else 8.0f * (cos(controller.pitch.toRadians())).pow(2) * ((state.noInputTimeRoll.get() - rollCorrectionTimer)).coerceIn(0.0, 1.0).toFloat()
val maxRollForce = maxRollCorrectionRate / 40.0
val rollArrivalDeg = 90.0
@@ -446,8 +450,8 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
// Set roll to zero if transitioning to noroll config
controller.rotateRoll(controller.roll * -1.0f)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalBird.handlingExpr!!)
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult ?: globalBird.mouseInputMult!!)
//Smooth out mouse input.
val smoothingSpeed = 4.0
@@ -491,8 +495,8 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
if (driver !is OrientationControllable) return Vec3.ZERO
val controller = (driver as OrientationControllable).orientationController
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBird.speedExpr!!) / 20.0
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult ?: globalBird.mouseInputMult!!)
//Smooth out mouse input.
val smoothingSpeed = 2.0
@@ -516,7 +520,7 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
// - Reduce pitch substantially when rolled and in a steep yaw. This prevents the player from ignoring a slow handling stat
// - Do not pitch at all when at or below hover speed
// - pitch faster at higher speeds
val p = 1.0 - vehicle.runtime.resolveDouble(settings.horizontalPitchExpr)
val p = 1.0 - vehicle.runtime.resolveDouble(settings.horizontalPitchExpr ?: globalBird.horizontalPitchExpr!!)
var localPitch = yInput * (1 - abs(sin(controller.roll.toRadians())).pow(2) * p * hypot(controller.forwardVector.x.toDouble(), controller.forwardVector.z.toDouble()).toFloat())
localPitch *= if (currSpeed > hoverSpeed || yInput > 0.0) RidingBehaviour.scaleToRange(currSpeed, 0.0, topSpeed).coerceIn(0.2, 1.0)
else 0.0
@@ -579,8 +583,8 @@ class BirdBehaviour : RidingBehaviour<BirdSettings, BirdState> {
vehicle: PokemonEntity,
driver: Player
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val glideTopSpeed = topSpeed * vehicle.runtime.resolveDouble(settings.glidespeedExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBird.speedExpr!!) / 20.0
val glideTopSpeed = topSpeed * vehicle.runtime.resolveDouble(settings.glideSpeedExpr ?: globalBird.glideSpeedExpr!!)
val currSpeed = state.rideVelocity.get().length()
// Must I ensure that topspeed is greater than minimum?
@@ -668,57 +672,56 @@ class BirdSettings : RidingBehaviourSettings {
override val key = BirdBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var infiniteAltitude: Expression = "false".asExpression()
var infiniteAltitude: Expression? = null
private set
var infiniteStamina: Expression = "false".asExpression()
var infiniteStamina: Expression? = null
private set
var timeToRollCorrect: Expression = "0.5".asExpression()
var timeToRollCorrect: Expression? = null
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 45.0, 10.0)".asExpression()
var horizontalPitchExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 0.2, 0.1)".asExpression()
var mouseInputMult: Expression = "q.get_ride_stats('SKILL', 'AIR', 1.2, 0.8)".asExpression()
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 20.0, 4.0)".asExpression()
var handlingExpr: Expression? = null
var horizontalPitchExpr: Expression? = null
var mouseInputMult: Expression? = null
var speedExpr: Expression? = null
// Seconds from stationary to top speed
var accelerationExpr: Expression = "q.get_ride_stats('ACCELERATION', 'AIR', 2.0, 8.0)".asExpression()
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'AIR', 15.0, 2.0)".asExpression()
var accelerationExpr: Expression? = null
var staminaExpr: Expression? = null
var glidespeedExpr: Expression = "q.get_ride_stats('JUMP', 'AIR', 2.0, 1.0)".asExpression()
var glideSpeedExpr: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(infiniteAltitude)
buffer.writeExpression(infiniteStamina)
buffer.writeExpression(glidespeedExpr)
buffer.writeExpression(handlingExpr)
buffer.writeExpression(horizontalPitchExpr)
buffer.writeExpression(mouseInputMult)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeExpression(timeToRollCorrect)
buffer.writeNullableExpression(infiniteAltitude)
buffer.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(glideSpeedExpr)
buffer.writeNullableExpression(handlingExpr)
buffer.writeNullableExpression(horizontalPitchExpr)
buffer.writeNullableExpression(mouseInputMult)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
buffer.writeNullableExpression(timeToRollCorrect)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
infiniteAltitude = buffer.readExpression()
infiniteStamina = buffer.readExpression()
glidespeedExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
horizontalPitchExpr = buffer.readExpression()
mouseInputMult = buffer.readExpression()
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
timeToRollCorrect = buffer.readExpression()
infiniteAltitude = buffer.readNullableExpression()
infiniteStamina = buffer.readNullableExpression()
glideSpeedExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
horizontalPitchExpr = buffer.readNullableExpression()
mouseInputMult = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
timeToRollCorrect = buffer.readNullableExpression()
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.air
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
@@ -37,6 +38,9 @@ class GliderBehaviour : RidingBehaviour<GliderSettings, RidingBehaviourState> {
override val key = KEY
val globalGlider: GliderSettings
get() = CobblemonRideSettings.glider
override fun getRidingStyle(settings: GliderSettings, state: RidingBehaviourState): RidingStyle {
return RidingStyle.AIR
}
@@ -53,7 +57,7 @@ class GliderBehaviour : RidingBehaviour<GliderSettings, RidingBehaviourState> {
}
override fun speed(settings: GliderSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
return vehicle.runtime.resolveFloat(settings.speed ?: globalGlider.speed!!)
}
override fun rotation(
@@ -72,8 +76,8 @@ class GliderBehaviour : RidingBehaviour<GliderSettings, RidingBehaviourState> {
driver: Player,
input: Vec3
): Vec3 {
val xVector = if (vehicle.runtime.resolveBoolean(settings.canStrafe)) driver.xxa.toDouble() else 0.0
val yVector = -vehicle.runtime.resolveDouble(settings.glideSpeed)
val xVector = if (vehicle.runtime.resolveBoolean(settings.canStrafe ?: globalGlider.canStrafe!!)) driver.xxa.toDouble() else 0.0
val yVector = -vehicle.runtime.resolveDouble(settings.glideSpeed ?: globalGlider.glideSpeed!!)
val zVector = driver.zza.toDouble()
return Vec3(xVector, yVector, zVector)
}
@@ -195,31 +199,30 @@ class GliderSettings : RidingBehaviourSettings {
override val key = GliderBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var glideSpeed: Expression = "0.1".asExpression()
var glideSpeed: Expression? = null
private set
var speed: Expression = "1.0".asExpression()
var speed: Expression? = null
private set
var canStrafe: Expression = "false".asExpression()
var canStrafe: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(glideSpeed)
buffer.writeExpression(speed)
buffer.writeExpression(canStrafe)
buffer.writeNullableExpression(glideSpeed)
buffer.writeNullableExpression(speed)
buffer.writeNullableExpression(canStrafe)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
glideSpeed = buffer.readExpression()
speed = buffer.readExpression()
canStrafe = buffer.readExpression()
glideSpeed = buffer.readNullableExpression()
speed = buffer.readNullableExpression()
canStrafe = buffer.readNullableExpression()
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.air
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
@@ -21,7 +22,16 @@ import com.cobblemon.mod.common.api.riding.sound.RideSoundSettingsList
import com.cobblemon.mod.common.api.riding.stats.RidingStat
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.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.resolveDouble
import com.cobblemon.mod.common.util.writeNullableExpression
import com.cobblemon.mod.common.util.writeRidingStats
import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sin
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -30,9 +40,6 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sin
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourState> {
companion object {
@@ -41,6 +48,8 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
}
override val key = KEY
val globalHelicopter: HelicopterSettings
get() = CobblemonRideSettings.helicopter
override fun getRidingStyle(settings: HelicopterSettings, state: RidingBehaviourState): RidingStyle {
return RidingStyle.AIR
@@ -93,8 +102,8 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
val runtime = vehicle.runtime
//If the player is not modulating height then hover
var yVel = if (driver.jumping) runtime.resolveDouble(settings.verticalVelocity)
else if (driver.isShiftKeyDown) -runtime.resolveDouble(settings.verticalVelocity)
var yVel = if (driver.jumping) runtime.resolveDouble(settings.verticalVelocity ?: globalHelicopter.verticalVelocity!!)
else if (driver.isShiftKeyDown) -runtime.resolveDouble(settings.verticalVelocity ?: globalHelicopter.verticalVelocity!!)
else (0.0)
yVel *= 0.25
@@ -290,36 +299,35 @@ class HelicopterSettings : RidingBehaviourSettings {
override val key = HelicopterBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var gravity: Expression = "1.0".asExpression()
var gravity: Expression? = null
private set
var horizontalAcceleration: Expression = "0.1".asExpression()
var horizontalAcceleration: Expression? = null
private set
var verticalVelocity: Expression = "1.0".asExpression()
var verticalVelocity: Expression? = null
private set
var speed: Expression = "1.0".asExpression()
var speed: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(gravity)
buffer.writeExpression(horizontalAcceleration)
buffer.writeExpression(verticalVelocity)
buffer.writeExpression(speed)
buffer.writeNullableExpression(gravity)
buffer.writeNullableExpression(horizontalAcceleration)
buffer.writeNullableExpression(verticalVelocity)
buffer.writeNullableExpression(speed)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
gravity = buffer.readExpression()
horizontalAcceleration = buffer.readExpression()
verticalVelocity = buffer.readExpression()
speed = buffer.readExpression()
gravity = buffer.readNullableExpression()
horizontalAcceleration = buffer.readNullableExpression()
verticalVelocity = buffer.readNullableExpression()
speed = buffer.readNullableExpression()
}
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.riding.behaviour.types.air
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonRideSettings
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
@@ -41,6 +42,8 @@ class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
}
override val key = KEY
val globalHover: HoverSettings
get() = CobblemonRideSettings.hover
override fun getRidingStyle(settings: HoverSettings, state: HoverState): RidingStyle {
return RidingStyle.AIR
@@ -105,7 +108,7 @@ class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
state: HoverState,
vehicle: PokemonEntity,
) {
val heightLimit = vehicle.runtime.resolveDouble(settings.jumpExpr)
val heightLimit = vehicle.runtime.resolveDouble(settings.jumpExpr ?: globalHover.jumpExpr!!)
val pos = vehicle.position()
val level = Minecraft.getInstance().player?.level() ?: return
val hit = level.clip(
@@ -126,9 +129,12 @@ class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
state: HoverState,
vehicle: PokemonEntity
) {
if (vehicle.runtime.resolveBoolean(settings.infiniteStamina ?: globalHover.infiniteStamina!!)) {
return
}
val stam = state.stamina.get()
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr)).toFloat() / 20.0f
val stamReplenishRate = (1.0f / vehicle.runtime.resolveDouble(settings.stamReplenishTimeSeconds) ).toFloat() / 20.0f // 2 seconds to replenish a full bar of stamina
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalHover.staminaExpr!!)).toFloat() / 20.0f
val stamReplenishRate = (1.0f / vehicle.runtime.resolveDouble(settings.stamReplenishTimeSeconds ?: globalHover.stamReplenishTimeSeconds!!) ).toFloat() / 20.0f // 2 seconds to replenish a full bar of stamina
val newStam = if (state.tooHigh.get()) max(0.0f, stam - stamDrainRate) else min(1.0f,stam + stamReplenishRate)
state.stamina.set(newStam)
@@ -175,8 +181,8 @@ class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr) / 20.0
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalHover.speedExpr!!) / 20.0
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalHover.handlingExpr!!) / 20.0
val maxYawDiff = 90.0f
// Normalize the current rotation diff
@@ -211,8 +217,8 @@ class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
driver: Player
): Vec3 {
// Convert these to their tick values
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr) * 20.0)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalHover.speedExpr!!) / 20.0
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHover.accelerationExpr!!) * 20.0)
var newVelocity = state.rideVelocity.get()
@@ -427,54 +433,61 @@ class HoverSettings : RidingBehaviourSettings {
override val key = HoverBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var canJump = "true".asExpression()
var infiniteStamina: Expression? = null
private set
var stamReplenishTimeSeconds = "2.0".asExpression()
var canJump: Expression? = null
private set
var stamReplenishTimeSeconds: Expression? = null
private set
// Speed in block per second
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 7.0, 1.0)".asExpression()
var speedExpr: Expression? = null
private set
// Acceleration in number of seconds to top speed
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'AIR', 2.0, 8.0)".asExpression()
var accelerationExpr: Expression? = null
private set
// Amount of seconds between boosts
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'AIR', 30.0, 2.0)".asExpression()
var staminaExpr: Expression? = null
private set
// Blocks before stamina drain
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'AIR', 16.0, 2.0)".asExpression()
var jumpExpr: Expression? = null
private set
// Turn rate in degrees per second when stationary
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 270.0, 45.0)".asExpression()
var handlingExpr: Expression? = null
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.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(canJump)
buffer.writeNullableExpression(stamReplenishTimeSeconds)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
}
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()
infiniteStamina = buffer.readNullableExpression()
canJump = buffer.readNullableExpression()
stamReplenishTimeSeconds = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
}
}
@@ -11,23 +11,35 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.air
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.behaviour.types.land.HorseSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.HorseState
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.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import com.cobblemon.mod.common.api.riding.sound.RideSoundSettingsList
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.config.CobblemonConfig
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.math.geometry.toRadians
import com.cobblemon.mod.common.util.readNullableExpression
import com.cobblemon.mod.common.util.readRidingStats
import com.cobblemon.mod.common.util.resolveDouble
import com.cobblemon.mod.common.util.toVec3d
import com.cobblemon.mod.common.util.writeNullableExpression
import com.cobblemon.mod.common.util.writeRidingStats
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import net.minecraft.client.Minecraft
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
@@ -36,7 +48,6 @@ import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Vector3f
import kotlin.math.*
class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
companion object {
@@ -49,6 +60,9 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
return RidingStyle.AIR
}
val globalJet: JetSettings
get() = CobblemonRideSettings.jet
val poseProvider = PoseProvider<JetSettings, JetState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.1 })
@@ -113,7 +127,7 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
) {
val stam = state.stamina.get()
var newStam = stam
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr)).toFloat() / 20.0f
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalJet.staminaExpr!!)).toFloat() / 20.0f
if (state.boosting.get()) {
newStam = max(0.0f,stam - stamDrainRate * 1.5f)
@@ -178,12 +192,12 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
vehicle: PokemonEntity,
driver: Player
) {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr) * 20.0)
val deccel = vehicle.runtime.resolveDouble(settings.deccelRate)//0.005
val minSpeed = topSpeed * vehicle.runtime.resolveDouble(settings.minSpeedFactor)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalJet.speedExpr!!) / 20.0
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalJet.accelerationExpr!!) * 20.0)
val deccel = vehicle.runtime.resolveDouble(settings.deccelRate ?: globalJet.deccelRate!!)//0.005
val minSpeed = topSpeed * vehicle.runtime.resolveDouble(settings.minSpeedFactor ?: globalJet.minSpeedFactor!!)
val speed = state.rideVelocity.get().z
val boostMult = vehicle.runtime.resolveDouble(settings.jumpExpr)
val boostMult = vehicle.runtime.resolveDouble(settings.jumpExpr ?: globalJet.jumpExpr!!)
val boostTopSpeed = topSpeed * boostMult
val boostAccel = accel * boostMult
@@ -258,7 +272,7 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
val cappedDeltaTime = min(deltaTime, 0.2)
//Get handling in degrees per second
val yawRotRate = vehicle.runtime.resolveDouble(settings.handlingYawExpr)
val yawRotRate = vehicle.runtime.resolveDouble(settings.handlingYawExpr ?: globalJet.handlingYawExpr!!)
//Base the change off of deltatime.
var handlingYaw = yawRotRate * (cappedDeltaTime)
@@ -339,7 +353,7 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
//Get handling in degrees per second
val handlingDebuff = if(state.stamina.get() == 0.0f) 0.5 else 1.0
var handling = vehicle.runtime.resolveDouble(settings.handlingExpr) * handlingDebuff
var handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalJet.handlingExpr!!) * handlingDebuff
//convert it to delta time
handling *= (cappedDeltaTime)
@@ -393,7 +407,7 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
//Get handling in degrees per second
val handlingDebuff = if(state.stamina.get() == 0.0f) 0.5 else 1.0
var handling = vehicle.runtime.resolveDouble(settings.handlingExpr) * handlingDebuff
var handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalJet.handlingExpr!!) * handlingDebuff
//convert it to delta time
handling *= (cappedDeltaTime)
@@ -547,72 +561,70 @@ class JetSettings : RidingBehaviourSettings {
override val key = JetBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var gravity: Expression = "0".asExpression()
var gravity: Expression? = null
private set
var deccelRate: Expression = "0.005".asExpression()
var deccelRate: Expression? = null
private set
// Mult to top speed in order to derive minSpeed
var minSpeedFactor: Expression = "0.25".asExpression()
var minSpeedFactor: Expression? = null
private set
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 50.0, 25.0)".asExpression()
var handlingYawExpr: Expression? = null
private set
// Make configurable by json
var infiniteStamina: Expression = "false".asExpression()
var infiniteStamina: Expression? = null
private set
// Boost power. Mult for top speed and accel while boosting
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'AIR', 2.0, 1.0)".asExpression()
var jumpExpr: Expression? = null
private set
// Turn rate in degrees per second
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 60.0, 10.0)".asExpression()
var handlingExpr: Expression? = null
private set
// Top Speed in blocks per second
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 24.0, 4.0)".asExpression()
var speedExpr: Expression? = null
private set
// Seconds to get to top speed
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'AIR', 2.0, 8.0)".asExpression()
var accelerationExpr: Expression? = null
private set
// Time in seconds to drain full bar of stamina flying
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'AIR', 60.0, 4.0)".asExpression()
var staminaExpr: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(gravity)
buffer.writeExpression(deccelRate)
buffer.writeExpression(minSpeedFactor)
buffer.writeExpression(handlingYawExpr)
buffer.writeExpression(infiniteStamina)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeNullableExpression(gravity)
buffer.writeNullableExpression(deccelRate)
buffer.writeNullableExpression(minSpeedFactor)
buffer.writeNullableExpression(handlingYawExpr)
buffer.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
gravity = buffer.readExpression()
deccelRate = buffer.readExpression()
minSpeedFactor = buffer.readExpression()
handlingYawExpr = buffer.readExpression()
infiniteStamina = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
gravity = buffer.readNullableExpression()
deccelRate = buffer.readNullableExpression()
minSpeedFactor = buffer.readNullableExpression()
handlingYawExpr = buffer.readNullableExpression()
infiniteStamina = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
}
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.air
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.CobblemonRideSettings
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
@@ -40,6 +41,8 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
}
override val key = KEY
val globalRocket: RocketSettings
get() = CobblemonRideSettings.rocket
override fun getRidingStyle(settings: RocketSettings, state: RocketState): RidingStyle {
return RidingStyle.AIR
@@ -84,7 +87,7 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
driver: Player
): Float {
// Use this as a "tick" function and check to see if the driver is "boosting"
if(vehicle.level().isClientSide) {
if (vehicle.level().isClientSide) {
handleBoosting(settings, state, vehicle, driver)
tickStamina(settings, state, vehicle, driver)
}
@@ -124,10 +127,14 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
) {
val stam = state.stamina.get()
if (vehicle.runtime.resolveBoolean(settings.infiniteStamina ?: globalRocket.infiniteStamina!!)) {
return
}
// Grab the boost time in seconds and convert to ticks. Then calculate the drain rate as inversely
// proportional to the number of ticks of boost thus making a full boost take x ticks
// in short: "Stamina drains slower at higher values and also replenishes slower"
val boostTime = vehicle.runtime.resolveDouble(settings.staminaExpr) * 20.0f
val boostTime = vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalRocket.staminaExpr!!) * 20.0f
val stamDrainRate = (1.0f / boostTime).toFloat()
val newStam = if(state.boosting.get() || driver.jumping) max(0.0f,stam - stamDrainRate) else stam
@@ -179,13 +186,13 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
var newMomentum = state.turnMomentum.get().toDouble()
// Degrees per tick
val maxTurnMomentum = vehicle.runtime.resolveDouble(settings.maxTurnRate) / 20.0f
val maxTurnMomentum = vehicle.runtime.resolveDouble(settings.maxTurnRate ?: globalRocket.maxTurnRate!!) / 20.0f
// Turn rate increase per tick. Based off number of seconds to get to max turn rate
val turningAcceleration = maxTurnMomentum / (vehicle.runtime.resolveDouble(settings.handlingExpr) * 20.0f)
val turningAcceleration = maxTurnMomentum / (vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalRocket.handlingExpr!!) * 20.0f)
val turnInput = (driver.xxa *-1.0f) * turningAcceleration
// Base boost stats off of normal turning stats
val boostHandlingMod = vehicle.runtime.resolveDouble(settings.boostHandlingMod)
val boostHandlingMod = vehicle.runtime.resolveDouble(settings.boostHandlingMod ?: globalRocket.boostHandlingMod!!)
val boostMaxTurnMomentum = maxTurnMomentum * boostHandlingMod
val boostTurnInput = turnInput * boostHandlingMod
@@ -230,9 +237,9 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val jump = vehicle.runtime.resolveDouble(settings.jumpExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalRocket.speedExpr!!)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalRocket.accelerationExpr!!)
val jump = vehicle.runtime.resolveDouble(settings.jumpExpr ?: globalRocket.jumpExpr!!)
var newVelocity = vehicle.deltaMovement
@@ -256,7 +263,7 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
(newVelocity.z + (accel * forwardInput.toDouble())))
} else if ((state.boosting.get())) {
val boostMod = vehicle.runtime.resolveDouble(settings.boostSpeedMod)
val boostMod = vehicle.runtime.resolveDouble(settings.boostSpeedMod ?: globalRocket.boostSpeedMod!!)
val boostSpeed = topSpeed * boostMod
val boostAccel = if(newVelocity.length() < boostSpeed) accel * (boostMod/1.5) else 0.0
val forwardInput = 1.0f
@@ -398,8 +405,8 @@ class RocketBehaviour : RidingBehaviour<RocketSettings, RocketState> {
driver: Player
): Float {
if (state.boosting.get()) {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val boostMod = vehicle.runtime.resolveDouble(settings.boostSpeedMod)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalRocket.speedExpr!!)
val boostMod = vehicle.runtime.resolveDouble(settings.boostSpeedMod ?: globalRocket.boostSpeedMod!!)
val normalizedBoostSpeed = RidingBehaviour.scaleToRange(state.rideVelocity.get().length(), topSpeed, topSpeed * boostMod)
return 1.0f + normalizedBoostSpeed.pow(2).toFloat() * 0.2f
} else {
@@ -499,60 +506,67 @@ class RocketSettings : RidingBehaviourSettings {
override val key = RocketBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var infiniteStamina: Expression? = null
private set
// Boost multiplier for speed
var boostSpeedMod: Expression = "5.0".asExpression()
var boostSpeedMod: Expression? = null
private set
// Boost multiplier for handling
var boostHandlingMod: Expression = "0.3".asExpression()
var boostHandlingMod: Expression? = null
private set
// Max turn rate in degrees per second
var maxTurnRate: Expression = "100.0".asExpression()
var maxTurnRate: Expression? = null
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 1.2, 0.6)".asExpression()
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 =
"q.get_ride_stats('ACCELERATION', 'AIR', (1.0 / (20.0 * 1.5)), (1.0 / (20.0 * 3.0))) * 0.5".asExpression()
var accelerationExpr: Expression? = null
private set
// air time in seconds
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'AIR', 20.0, 10.0)".asExpression()
var staminaExpr: Expression? = null
private set
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'AIR', 2.0, 1.0)".asExpression()
var jumpExpr: Expression? = null
private set
// How long it takes to get to max turn rate from rest (in seconds)
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 0.5, 3.0)".asExpression()
var handlingExpr: Expression? = null
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.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(boostSpeedMod)
buffer.writeNullableExpression(boostHandlingMod)
buffer.writeNullableExpression(maxTurnRate)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
}
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()
infiniteStamina = buffer.readNullableExpression()
boostSpeedMod = buffer.readNullableExpression()
boostHandlingMod = buffer.readNullableExpression()
maxTurnRate = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
}
}
class RocketState : RidingBehaviourState() {
@@ -387,9 +387,10 @@ open class CompositeSettings : RidingBehaviourSettings {
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeRidingStats(stats)
buffer.writeResourceLocation(key)
buffer.writeResourceLocation(transitionStrategy)
buffer.writeResourceLocation(defaultBehaviour.key)
defaultBehaviour.encode(buffer)
buffer.writeResourceLocation(alternateBehaviour.key)
alternateBehaviour.encode(buffer)
}
@@ -41,6 +41,10 @@ interface CompositeRidingStrategy<T : CompositeSettings> {
toState: RidingBehaviourState,
toSettings: RidingBehaviourSettings
) {
if (vehicle.level().isClientSide) {
val fromSettings = if (settings.defaultBehaviour == toSettings) settings.alternateBehaviour else settings.defaultBehaviour
}
toState.stamina.set(fromState.stamina.get())
toState.rideVelocity.set(fromState.rideVelocity.get())
fromState.reset()
@@ -9,16 +9,34 @@
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.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
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.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 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 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.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -31,8 +49,6 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Matrix3f
import kotlin.math.*
class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
companion object {
@@ -40,6 +56,8 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
}
override val key = KEY
val globalHorse: HorseSettings
get() = CobblemonRideSettings.horse
override fun getRidingStyle(settings: HorseSettings, state: HorseState): RidingStyle {
return RidingStyle.LAND
@@ -134,8 +152,13 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
vehicle: PokemonEntity,
) {
val stam = state.stamina.get()
if (vehicle.runtime.resolveBoolean(settings.infiniteStamina ?: globalHorse.infiniteStamina!!)) {
return
}
var newStam = stam
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr)).toFloat() / 20.0f
val stamDrainRate = (1.0f / vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalHorse.staminaExpr!!)).toFloat() / 20.0f
if (state.sprinting.get()) {
newStam = max(0.0f,stam - stamDrainRate)
@@ -185,10 +208,10 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalHorse.speedExpr!!)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalHorse.handlingExpr!!)
val walkHandlingBoost = 5
val maxYawDiff = vehicle.runtime.resolveFloat(settings.lookYawLimit)
val maxYawDiff = vehicle.runtime.resolveFloat(settings.lookYawLimit ?: globalHorse.lookYawLimit!!)
// Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot).coerceIn(-maxYawDiff,maxYawDiff)
@@ -232,13 +255,13 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val canSprint = vehicle.runtime.resolveBoolean(settings.canSprint)
val canJump = vehicle.runtime.resolveBoolean(settings.canJump)
val jumpForce = vehicle.runtime.resolveDouble(settings.jumpExpr) * 0.75
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
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 accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr) * 20.0)
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHorse.accelerationExpr!!) * 20.0)
var activeInput = false
/******************************************************
@@ -271,7 +294,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
// 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)
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)
@@ -513,59 +536,67 @@ class HorseSettings : RidingBehaviourSettings {
override val key = HorseBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var canJump = "true".asExpression()
var infiniteStamina: Expression? = null
private set
var canJump: Expression? = null
private set
var canSprint = "true".asExpression()
var canSprint: Expression? = null
private set
var lookYawLimit = "90.0f".asExpression()
var lookYawLimit: Expression? = null
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.2, 0.1)".asExpression()
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 =
"q.get_ride_stats('ACCELERATION', 'LAND', 0.1, 12.0)".asExpression()
var accelerationExpr: Expression? = null
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'LAND', 60.0, 4.0)".asExpression()
var staminaExpr: Expression? = null
private set
//Between a one block jump and a six block jump
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'LAND', 1.6, 0.2)".asExpression()
var jumpExpr: Expression? = null
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'LAND', 90.0, 30.0)".asExpression()
var handlingExpr: Expression? = null
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)
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)
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
canJump = buffer.readExpression()
canSprint = buffer.readExpression()
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()
}
}
@@ -10,18 +10,36 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.land
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.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.SidedRidingState
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.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.blockPositionsAsListRounded
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.geometry.toRadians
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 kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sign
import net.minecraft.core.Direction
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -32,12 +50,6 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Matrix3f
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sign
class MinekartBehaviour : RidingBehaviour<MinekartSettings, MinekartState> {
companion object {
@@ -45,6 +57,8 @@ class MinekartBehaviour : RidingBehaviour<MinekartSettings, MinekartState> {
}
override val key = KEY
val globalMinekart: MinekartSettings
get() = CobblemonRideSettings.minekart
override fun getRidingStyle(settings: MinekartSettings, state: MinekartState): RidingStyle {
return RidingStyle.LAND
@@ -84,7 +98,7 @@ class MinekartBehaviour : RidingBehaviour<MinekartSettings, MinekartState> {
driver: Player
): Float {
val boostMax = vehicle.runtime.resolveFloat(settings.boostLimit)
val boostMax = vehicle.runtime.resolveFloat(settings.boostLimit ?: globalMinekart.boostLimit!!)
//TODO: should this be by how much turn has accumulated or simply time turning... or both?
val boostPerSecond = 20.0f
val boostLoss = 40.0f
@@ -142,8 +156,8 @@ class MinekartBehaviour : RidingBehaviour<MinekartSettings, MinekartState> {
var newMomentum = state.turnMomentum.get().toDouble()
//TODO: maybe tie this to max turnspeeds rather than the turn acceleration
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val turningAcceleration = (vehicle.runtime.resolveDouble(settings.handlingExpr) * 1.5 / 20.0f) / 20.0f * 4.0
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalMinekart.speedExpr!!)
val turningAcceleration = (vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalMinekart.handlingExpr!!) * 1.5 / 20.0f) / 20.0f * 4.0
val turnInput = (driver.xxa *-1.0f) * turningAcceleration
val driftInput = turnInput * 0.25f
@@ -202,9 +216,9 @@ class MinekartBehaviour : RidingBehaviour<MinekartSettings, MinekartState> {
): Vec3 {
// Check to see if the ride should be walking or sprinting
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) * 0.6 * 2.0
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalMinekart.speedExpr!!) * 0.6 * 2.0
val topSpeed = if (state.drifting.get()) rideTopSpeed * 0.7 else rideTopSpeed
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr) * 0.3 * 3 * 2.0
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalMinekart.accelerationExpr!!) * 0.3 * 3 * 2.0
val driftAngle = 20.0f
//Align the direction of this vector with the vehicles current heading.
@@ -327,7 +341,7 @@ class MinekartBehaviour : RidingBehaviour<MinekartSettings, MinekartState> {
vehicle: PokemonEntity,
driver: Player
): Boolean {
return vehicle.runtime.resolveBoolean(settings.canJump)
return vehicle.runtime.resolveBoolean(settings.canJump ?: globalMinekart.canJump!!)
}
override fun setRideBar(
@@ -447,45 +461,57 @@ class MinekartSettings : RidingBehaviourSettings {
override val key = MinekartBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var canJump = "true".asExpression()
var infiniteStamina: Expression? = null
private set
var canJump: Expression? = null
private set
var boostLimit = "100.0f".asExpression()
var boostLimit: Expression? = null
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.3)".asExpression()
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 =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 1.5)), (1.0 / (20.0 * 5.0)))".asExpression()
var accelerationExpr: Expression? = null
private set
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'LAND', 30.0, 10.0)".asExpression()
var staminaExpr: Expression? = null
private set
//Between a one block jump and a ten block jump
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'LAND', 10.0, 1.0)".asExpression()
var jumpExpr: Expression? = null
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'LAND', 140.0, 20.0)".asExpression()
var handlingExpr: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(canJump)
buffer.writeExpression(boostLimit)
buffer.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(canJump)
buffer.writeNullableExpression(boostLimit)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
canJump = buffer.readExpression()
boostLimit = buffer.readExpression()
infiniteStamina = buffer.readNullableExpression()
canJump = buffer.readNullableExpression()
boostLimit = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
}
}
@@ -10,18 +10,35 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.land
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.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.SidedRidingState
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.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.blockPositionsAsListRounded
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.geometry.toRadians
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.toVec3d
import com.cobblemon.mod.common.util.writeNullableExpression
import com.cobblemon.mod.common.util.writeRidingStats
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sign
import net.minecraft.core.Direction
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -33,10 +50,6 @@ import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Matrix3f
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sign
class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
companion object {
@@ -44,6 +57,8 @@ class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
}
override val key = KEY
val globalVehicle: VehicleSettings
get() = CobblemonRideSettings.vehicle
override fun getRidingStyle(settings: VehicleSettings, state: VehicleState): RidingStyle {
return RidingStyle.LAND
@@ -126,7 +141,7 @@ class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
var newMomentum = state.turnMomentum.get().toDouble()
// Grab turningAcceleration and divide 20 twice to get
val turningAcceleration = (vehicle.runtime.resolveDouble(settings.handlingExpr) * 1.5 / 20.0f) / 20.0f * 4.0
val turningAcceleration = (vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalVehicle.handlingExpr!!) * 1.5 / 20.0f) / 20.0f * 4.0
val turnInput = (driver.xxa *-1.0f) * turningAcceleration
val maxTurnMomentum = 80.0f / 20.0f
@@ -137,7 +152,7 @@ class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
if(state.drifting.get() || state.inAir.get()) {
if( newMomentum < driftMaxTurnMomentum) {
driftTurnInput = driftTurnInput * (vehicle.deltaMovement.horizontalDistance() / vehicle.runtime.resolveDouble(settings.speedExpr))
driftTurnInput = driftTurnInput * (vehicle.deltaMovement.horizontalDistance() / vehicle.runtime.resolveDouble(settings.speedExpr ?: globalVehicle.speedExpr!!))
newMomentum += driftTurnInput
}
newMomentum = lerp(newMomentum, 0.0, 0.03)
@@ -177,10 +192,10 @@ class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
// Check to see if the ride should be walking or sprinting
//val walkSpeed = getWalkSpeed(vehicle)
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) * 0.6 * 2.0
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalVehicle.speedExpr!!) * 0.6 * 2.0
val topSpeed = if (state.drifting.get()) rideTopSpeed * 0.5 else rideTopSpeed
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr) * 0.3 * 3 * 2.0
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalVehicle.accelerationExpr!!) * 0.3 * 3 * 2.0
//Flag for determining if player is actively inputting
var activeInput = false
@@ -250,7 +265,7 @@ class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
}
//TODO: Change this so its tied to a jumping stat and representative of the amount of jumps
val canJump = vehicle.runtime.resolveBoolean(settings.canJump)
val canJump = vehicle.runtime.resolveBoolean(settings.canJump ?: globalVehicle.canJump!!)
//Jump the thang!
if (driver.jumping && vehicle.onGround() && canJump) {
val jumpForce = 0.5
@@ -296,7 +311,7 @@ class VehicleBehaviour : RidingBehaviour<VehicleSettings, VehicleState> {
vehicle: PokemonEntity,
driver: Player
): Boolean {
return vehicle.runtime.resolveBoolean(settings.canJump)
return vehicle.runtime.resolveBoolean(settings.canJump ?: globalVehicle.canJump!!)
}
override fun setRideBar(
@@ -412,66 +427,79 @@ class VehicleSettings : RidingBehaviourSettings {
override val key = VehicleBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var canJump = "true".asExpression()
var infiniteStamina: Expression? = null
private set
var speed = "0.3".asExpression()
var canJump: Expression? = null
private set
var driveFactor = "1.0".asExpression()
var speed: Expression? = null
private set
var reverseDriveFactor = "0.25".asExpression()
var driveFactor: Expression? = null
private set
var rotationSpeed = "45/20".asExpression()
var reverseDriveFactor: Expression? = null
private set
var lookYawLimit = "101".asExpression()
var rotationSpeed: Expression? = null
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.3)".asExpression()
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 =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 1.5)), (1.0 / (20.0 * 5.0)))".asExpression()
var accelerationExpr: Expression? = null
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()
var staminaExpr: Expression? = null
private set
//Between a one block jump and a ten block jump
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'LAND', 10.0, 1.0)".asExpression()
var jumpExpr: Expression? = null
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'LAND', 140.0, 20.0)".asExpression()
var handlingExpr: Expression? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(canJump)
buffer.writeExpression(speed)
buffer.writeExpression(driveFactor)
buffer.writeExpression(reverseDriveFactor)
buffer.writeExpression(rotationSpeed)
buffer.writeExpression(lookYawLimit)
buffer.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(canJump)
buffer.writeNullableExpression(speed)
buffer.writeNullableExpression(driveFactor)
buffer.writeNullableExpression(reverseDriveFactor)
buffer.writeNullableExpression(rotationSpeed)
buffer.writeNullableExpression(lookYawLimit)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
canJump = buffer.readExpression()
speed = buffer.readExpression()
driveFactor = buffer.readExpression()
reverseDriveFactor = buffer.readExpression()
rotationSpeed = buffer.readExpression()
lookYawLimit = buffer.readExpression()
infiniteStamina = buffer.readNullableExpression()
canJump = buffer.readNullableExpression()
speed = buffer.readNullableExpression()
driveFactor = buffer.readNullableExpression()
reverseDriveFactor = buffer.readNullableExpression()
rotationSpeed = buffer.readNullableExpression()
lookYawLimit = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
}
}
@@ -8,16 +8,33 @@
package com.cobblemon.mod.common.api.riding.behaviour.types.liquid
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.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.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
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 kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import net.minecraft.core.BlockPos
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
@@ -28,9 +45,6 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
companion object {
@@ -38,6 +52,8 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
}
override val key = KEY
val globalBoat: BoatSettings
get() = CobblemonRideSettings.boat
override fun getRidingStyle(settings: BoatSettings, state: BoatState): RidingStyle {
return RidingStyle.LIQUID
@@ -87,7 +103,7 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
if (!state.isVehicleSprinting.get()) {
if (state.staminaBuffer.get() >= 20) {
val staminaIncrease = vehicle.runtime.resolveDouble(settings.staminaIncreaseExpr)
val staminaIncrease = vehicle.runtime.resolveDouble(settings.staminaIncreaseExpr ?: globalBoat.staminaIncreaseExpr!!)
state.stamina.set(min(1.0f, state.stamina.get() + 0.01f * staminaIncrease.toFloat()))
}
}
@@ -134,14 +150,14 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
}
private fun applyVelocityFromInput(velocity: Vec3, vehicle: PokemonEntity, driver: Player, settings: BoatSettings, state: BoatState): Vec3 {
val speed = vehicle.runtime.resolveDouble(settings.speedExpr)
val acceleration = speed / (vehicle.runtime.resolveDouble(settings.accelerationExpr) * 20)
val speed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalBoat.speedExpr!!)
val acceleration = speed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalBoat.accelerationExpr!!) * 20)
if (state.jumpBuffer.get() != -1 || !(vehicle.isInWater || vehicle.isUnderWater)) {
return velocity
}
val sprintModifier = vehicle.runtime.resolveDouble(settings.sprintSpeedModifier)
val sprintModifier = vehicle.runtime.resolveDouble(settings.sprintSpeedModifier ?: globalBoat.sprintSpeedModifier!!)
val activeSprintModifier = if (state.isVehicleSprinting.get() && hasStamina(state)) sprintModifier else 1.0
val forwardInput = driver.zza.toDouble()
val delta = when {
@@ -164,7 +180,7 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
if (!driver.jumping) return velocity // Not jumping
if (state.jumpBuffer.get() != -1) return velocity // Already jumped very recently
val jumpStrength = vehicle.runtime.resolveDouble(settings.jumpStrengthExpr)
val jumpStrength = vehicle.runtime.resolveDouble(settings.jumpStrengthExpr ?: globalBoat.jumpStrengthExpr!!)
state.jumpBuffer.set(0)
return Vec3(velocity.x, velocity.y + jumpStrength, velocity.z)
}
@@ -178,20 +194,20 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
return Vec3(velocity.x, 0.0, velocity.z)
}
}
val terminalVelocity = vehicle.runtime.resolveDouble(settings.terminalVelocity)
val terminalVelocity = vehicle.runtime.resolveDouble(settings.terminalVelocity ?: globalBoat.terminalVelocity!!)
val gravity = (9.8 / ( 20.0)) * 0.2
return Vec3(velocity.x, max(velocity.y - gravity, terminalVelocity), velocity.z)
}
private fun shouldFloatHigher(vehicle: PokemonEntity, settings: BoatSettings): Boolean {
val surfaceOffset = vehicle.runtime.resolveFloat(settings.surfaceLevelOffset)
val surfaceOffset = vehicle.runtime.resolveFloat(settings.surfaceLevelOffset ?: globalBoat.surfaceLevelOffset!!)
val blockPos = BlockPos.containing(vehicle.x, vehicle.eyeY + surfaceOffset, vehicle.z)
val fluidState = vehicle.level().getFluidState(blockPos)
return !fluidState.isEmpty
}
private fun applyStrafeRotation(vehicle: PokemonEntity, driver: Player, settings: BoatSettings, state: BoatState) {
val skillModifier = vehicle.runtime.resolveDouble(settings.rotationspeedModifierExpr)
val skillModifier = vehicle.runtime.resolveDouble(settings.rotationSpeedModifierExpr ?: globalBoat.rotationSpeedModifierExpr!!)
val strafe = driver.xxa
if (abs(strafe) > 0) {
val increase = if (strafe > 0) -1 else 1
@@ -204,7 +220,10 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
}
private fun consumeStamina(vehicle: PokemonEntity, driver: Player, settings: BoatSettings, state: BoatState, drain: Float) {
val staminaModifier = vehicle.runtime.resolveFloat(settings.staminaDecreaseExpr)
val staminaModifier = vehicle.runtime.resolveFloat(settings.staminaDecreaseExpr ?: globalBoat.staminaDecreaseExpr!!)
if (staminaModifier == 0F) {
return
}
state.stamina.set(max(0f, state.stamina.get() - drain / staminaModifier))
if (state.stamina.get() == 0f) {
state.isVehicleSprinting.set(false)
@@ -310,7 +329,7 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
vehicle: PokemonEntity,
driver: Player
): Float {
val sprintFov = vehicle.runtime.resolveFloat(settings.sprintFovModifier)
val sprintFov = vehicle.runtime.resolveFloat(settings.sprintFovModifier ?: globalBoat.sprintFovModifier!!)
return if (state.isVehicleSprinting.get()) sprintFov else 1.0f
}
@@ -355,7 +374,7 @@ class BoatBehaviour : RidingBehaviour<BoatSettings, BoatState> {
state: BoatState,
vehicle: PokemonEntity
): Boolean {
return vehicle.runtime.resolveBoolean(settings.rotatePokemonHead)
return vehicle.runtime.resolveBoolean(settings.rotatePokemonHead ?: globalBoat.rotatePokemonHead!!)
}
override fun shouldRotateRiderHead(
@@ -385,48 +404,67 @@ class BoatSettings : RidingBehaviourSettings {
override val stats = mutableMapOf<RidingStat, IntRange>()
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
var terminalVelocity = "-2.0".asExpression()
var terminalVelocity: Expression? = null
private set
var rotatePokemonHead = "true".asExpression()
var rotatePokemonHead: Expression? = null
private set
var staminaIncreaseExpr = "q.get_ride_stats('STAMINA', 'LIQUID', 2.0, 1.0)".asExpression()
var staminaIncreaseExpr: Expression? = null
private set
var staminaDecreaseExpr = "q.get_ride_stats('STAMINA', 'LIQUID', 5.0, 1.0)".asExpression()
var staminaDecreaseExpr: Expression? = null
private set
var rotationspeedModifierExpr = "q.get_ride_stats('SKILL', 'LIQUID', 1.5, 0.5)".asExpression()
var rotationSpeedModifierExpr: Expression? = null
private set
var jumpStrengthExpr = "q.get_ride_stats('JUMP', 'LIQUID', 2.5, 1.0)".asExpression()
var jumpStrengthExpr: Expression? = null
private set
var speedExpr = "q.get_ride_stats('SPEED', 'LIQUID', 2.0, 0.5)".asExpression()
var speedExpr: Expression? = null
private set
var accelerationExpr = "q.get_ride_stats('ACCELERATION', 'LIQUID', 0.1, 12.0)".asExpression()
var accelerationExpr: Expression? = null
private set
var sprintSpeedModifier = "q.get_ride_stats('JUMP', 'LIQUID', 1.5, 1.25)".asExpression()
var sprintSpeedModifier: Expression? = null
private set
var sprintFovModifier = "1.2".asExpression()
var sprintFovModifier: Expression? = null
var surfaceLevelOffset = "0".asExpression()
var surfaceLevelOffset: Expression? = null
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(terminalVelocity)
buffer.writeNullableExpression(terminalVelocity)
buffer.writeNullableExpression(rotatePokemonHead)
buffer.writeNullableExpression(staminaIncreaseExpr)
buffer.writeNullableExpression(staminaDecreaseExpr)
buffer.writeNullableExpression(rotationSpeedModifierExpr)
buffer.writeNullableExpression(jumpStrengthExpr)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(sprintSpeedModifier)
buffer.writeNullableExpression(sprintFovModifier)
buffer.writeNullableExpression(surfaceLevelOffset)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
terminalVelocity = buffer.readExpression()
terminalVelocity = buffer.readNullableExpression()
rotatePokemonHead = buffer.readNullableExpression()
staminaIncreaseExpr = buffer.readNullableExpression()
staminaDecreaseExpr = buffer.readNullableExpression()
rotationSpeedModifierExpr = buffer.readNullableExpression()
jumpStrengthExpr = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
sprintSpeedModifier = buffer.readNullableExpression()
sprintFovModifier = buffer.readNullableExpression()
surfaceLevelOffset = buffer.readNullableExpression()
}
}
@@ -8,10 +8,14 @@
package com.cobblemon.mod.common.api.riding.behaviour.types.liquid
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.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
@@ -21,6 +25,7 @@ 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.readRidingStats
import com.cobblemon.mod.common.util.writeNullable
import com.cobblemon.mod.common.util.writeRidingStats
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
@@ -38,6 +43,8 @@ class BurstBehaviour : RidingBehaviour<BurstSettings, BurstState> {
}
override val key = KEY
val globalBurst: BurstSettings
get() = CobblemonRideSettings.burst
override fun getRidingStyle(settings: BurstSettings, state: BurstState): RidingStyle {
return RidingStyle.LIQUID
@@ -67,7 +74,7 @@ class BurstBehaviour : RidingBehaviour<BurstSettings, BurstState> {
vehicle: PokemonEntity,
driver: Player
): Float {
if(state.dashing.get()) {
if (state.dashing.get()) {
state.ticks.set(state.ticks.get() + 1)
if(state.ticks.get() >= DASH_TICKS) {
state.dashing.set(false)
@@ -77,7 +84,7 @@ class BurstBehaviour : RidingBehaviour<BurstSettings, BurstState> {
}
state.dashing.set(true)
return settings.dashSpeed
return settings.dashSpeed ?: globalBurst.dashSpeed!!
}
override fun rotation(
@@ -239,22 +246,21 @@ class BurstSettings : RidingBehaviourSettings {
override val key = BurstBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var dashSpeed = 1F
var dashSpeed: Float? = null
private set
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeFloat(dashSpeed)
buffer.writeNullable(dashSpeed) { buf, speed -> buf.writeFloat(speed) }
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
dashSpeed = buffer.readFloat()
dashSpeed = buffer.readNullable { buf -> buf.readFloat() }
}
}
@@ -10,21 +10,33 @@ package com.cobblemon.mod.common.api.riding.behaviour.types.liquid
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
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.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
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.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.geometry.toDegrees
import com.cobblemon.mod.common.util.math.geometry.toRadians
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.toVec3d
import com.cobblemon.mod.common.util.writeNullableExpression
import com.cobblemon.mod.common.util.writeRidingStats
import kotlin.math.*
import net.minecraft.client.Minecraft
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -35,18 +47,6 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
import org.joml.Vector3f
import kotlin.math.abs
import kotlin.math.asin
import kotlin.math.cos
import kotlin.math.hypot
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sign
import kotlin.math.sin
import kotlin.math.sqrt
class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
companion object {
@@ -54,6 +54,8 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
}
override val key = KEY
val globalDolphin: DolphinSettings
get() = CobblemonRideSettings.dolphin
override fun getRidingStyle(settings: DolphinSettings, state: DolphinState): RidingStyle {
return RidingStyle.LIQUID
@@ -117,10 +119,14 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
) {
val stam = state.stamina.get()
if (vehicle.runtime.resolveBoolean(settings.infiniteStamina ?: globalDolphin.infiniteStamina!!)) {
return
}
// Grab the boost time in seconds and convert to ticks. Then calculate the drain rate as inversely
// proportional to the number of ticks of boost thus making a full boost take x ticks
// in short: "Stamina drains slower at higher values and also replenishes slower"
val boostTime = vehicle.runtime.resolveDouble(settings.staminaExpr) * 20.0f
val boostTime = vehicle.runtime.resolveDouble(settings.staminaExpr ?: globalDolphin.staminaExpr!!) * 20.0f
val stamDrainRate = (1.0f / boostTime).toFloat()
val newStam = if (state.boosting.get()) max(0.0f,stam - stamDrainRate)
@@ -149,9 +155,9 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
val controller = (driver as OrientationControllable).orientationController
val runtime = vehicle.runtime
val boostMod = if (state.boosting.get()) runtime.resolveDouble(settings.jumpExpr) else 1.0
val topSpeed = (vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0) * boostMod
val accel = (topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr) * 20.0)) * boostMod
val boostMod = if (state.boosting.get()) runtime.resolveDouble(settings.jumpExpr ?: globalDolphin.jumpExpr!!) else 1.0
val topSpeed = (vehicle.runtime.resolveDouble(settings.speedExpr ?: globalDolphin.speedExpr!!) / 20.0) * boostMod
val accel = (topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalDolphin.accelerationExpr!!) * 20.0)) * boostMod
/*********************************************
* Breaching logic
@@ -189,8 +195,8 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
}
val currSpeed = state.speed.get()
val strafeFactor = runtime.resolveDouble(settings.strafeFactor)
val reverseDriveFactor = runtime.resolveDouble(settings.reverseDriveFactor)
val strafeFactor = runtime.resolveDouble(settings.strafeFactor ?: globalDolphin.strafeFactor!!)
val reverseDriveFactor = runtime.resolveDouble(settings.reverseDriveFactor ?: globalDolphin.reverseDriveFactor!!)
val f = -driver.xxa * strafeFactor
when {
driver.zza > 0.0 -> state.speed.set(min(topSpeed, currSpeed + accel))
@@ -225,8 +231,8 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
val currSpeed = vehicle.deltaMovement.length()
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalDolphin.handlingExpr!!)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalDolphin.speedExpr!!) / 20.0
val yawDeltaDeg = deltaTime * handling * sin(Math.toRadians(controller.roll.toDouble())).pow(2) * sin(Math.toRadians(controller.roll.toDouble())).sign
val trueYawDelt = yawDeltaDeg * abs(cos(Math.toRadians(controller.pitch.toDouble()))) * sqrt(RidingBehaviour.scaleToRange(currSpeed, 0.0, topSpeed))
@@ -253,7 +259,7 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
// Calculate correcting roll force.
// Mult by cos(pitch) to ensure that it doesn't roll correct at when diving or climbing
val currSpeed = vehicle.deltaMovement.length()
val rollCorrectionTimer = vehicle.runtime.resolveDouble(settings.timeToRollCorrect)
val rollCorrectionTimer = vehicle.runtime.resolveDouble(settings.timeToRollCorrect ?: globalDolphin.timeToRollCorrect!!)
val maxRollCorrectionRate = if (!(vehicle.isInWater || vehicle.isUnderWater)) 15.0f
else 10.0f * (cos(controller.pitch.toRadians())).pow(2) * ((state.noInputTime.get() - rollCorrectionTimer) * 2).coerceIn(0.0, 1.0).toFloat()
val maxRollForce = maxRollCorrectionRate / 40.0
@@ -374,8 +380,8 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
controller.rotateRoll(controller.roll * -1.0f)
val boostingHandleDebuff = if (state.boosting.get()) 0.2 else 1.0
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr) * boostingHandleDebuff
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult)
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr ?: globalDolphin.handlingExpr!!) * boostingHandleDebuff
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult ?: globalDolphin.mouseInputMult!!)
//Smooth out mouse input.
val smoothingSpeed = 4.0
@@ -418,9 +424,9 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
): Vec3 {
if (driver !is OrientationControllable) return Vec3.ZERO
val controller = (driver as OrientationControllable).orientationController
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr) / 20.0
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalDolphin.speedExpr!!) / 20.0
val boostingHandleDebuff = if (state.boosting.get()) 0.2 else 1.0
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult) * boostingHandleDebuff
val mouseInputMult = vehicle.runtime.resolveDouble(settings.mouseInputMult ?: globalDolphin.mouseInputMult!!) * boostingHandleDebuff
//Smooth out mouse input.
val smoothingSpeed = 4.0
@@ -439,7 +445,7 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
// - Reduce pitch substantially when rolled and in a steep yaw. This prevents the player from ignoring a slow handling stat
// - Do not pitch at all when at or below hover speed
// - pitch faster at higher speeds
val p = 1.0 - vehicle.runtime.resolveDouble(settings.horizontalPitchExpr)
val p = 1.0 - vehicle.runtime.resolveDouble(settings.horizontalPitchExpr ?: globalDolphin.horizontalPitchExpr!!)
val localPitch = yInput * (1 - abs(sin(controller.roll.toRadians())) * p * hypot(controller.forwardVector.x.toDouble(), controller.forwardVector.z.toDouble()).toFloat())
// localPitch *= if (currSpeed > hoverSpeed) RidingBehaviour.scaleToRange(currSpeed, hoverSpeed, topSpeed)
// else 0.0
@@ -560,62 +566,66 @@ class DolphinSettings : RidingBehaviourSettings {
override val key = DolphinBehaviour.KEY
override val stats = mutableMapOf<RidingStat, IntRange>()
var canJump = "true".asExpression()
var infiniteStamina: Expression? = null
private set
var reverseDriveFactor = "0.25".asExpression()
var canJump: Expression? = null
private set
var strafeFactor = "0.2".asExpression()
var reverseDriveFactor: Expression? = null
private set
var timeToRollCorrect: Expression = "0.5".asExpression()
var strafeFactor: Expression? = null
private set
var timeToRollCorrect: Expression? = null
private set
// Boost influence when boosting
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'LIQUID', 2.2, 1.2)".asExpression()
var jumpExpr: Expression? = null
// Yaw rate in degrees per second
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'LIQUID', 100.0, 45.0)".asExpression()
var horizontalPitchExpr: Expression = "q.get_ride_stats('SKILL', 'LIQUID', 0.3, 0.2)".asExpression()
var mouseInputMult: Expression = "q.get_ride_stats('SKILL', 'LIQUID', 1.2, 0.8)".asExpression()
var handlingExpr: Expression? = null
var horizontalPitchExpr: Expression? = null
var mouseInputMult: Expression? = null
// Top speed in Bl/s
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LIQUID', 15.0, 5.0)".asExpression()
var speedExpr: Expression? = null
// Seconds to get to top speed
var accelerationExpr: Expression = "q.get_ride_stats('ACCELERATION', 'LIQUID', 2.0, 5.0)".asExpression()
var accelerationExpr: Expression? = null
// Seconds of boost
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'LIQUID', 7.0, 3.0)".asExpression()
var staminaExpr: Expression? = null
var rideSounds: RideSoundSettingsList = RideSoundSettingsList()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeRidingStats(stats)
rideSounds.encode(buffer)
buffer.writeExpression(canJump)
buffer.writeExpression(reverseDriveFactor)
buffer.writeExpression(strafeFactor)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
buffer.writeExpression(horizontalPitchExpr)
buffer.writeExpression(mouseInputMult)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeNullableExpression(infiniteStamina)
buffer.writeNullableExpression(canJump)
buffer.writeNullableExpression(reverseDriveFactor)
buffer.writeNullableExpression(strafeFactor)
buffer.writeNullableExpression(jumpExpr)
buffer.writeNullableExpression(handlingExpr)
buffer.writeNullableExpression(horizontalPitchExpr)
buffer.writeNullableExpression(mouseInputMult)
buffer.writeNullableExpression(speedExpr)
buffer.writeNullableExpression(accelerationExpr)
buffer.writeNullableExpression(staminaExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
stats.putAll(buffer.readRidingStats())
rideSounds = RideSoundSettingsList.decode(buffer)
canJump = buffer.readExpression()
reverseDriveFactor = buffer.readExpression()
strafeFactor = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
horizontalPitchExpr = buffer.readExpression()
mouseInputMult = buffer.readExpression()
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
infiniteStamina = buffer.readNullableExpression()
canJump = buffer.readNullableExpression()
reverseDriveFactor = buffer.readNullableExpression()
strafeFactor = buffer.readNullableExpression()
jumpExpr = buffer.readNullableExpression()
handlingExpr = buffer.readNullableExpression()
horizontalPitchExpr = buffer.readNullableExpression()
mouseInputMult = buffer.readNullableExpression()
speedExpr = buffer.readNullableExpression()
accelerationExpr = buffer.readNullableExpression()
staminaExpr = buffer.readNullableExpression()
}
}
@@ -24,14 +24,12 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.client.effect.PokeSnackBlockParticlesPacket
import com.cobblemon.mod.common.util.math.pow
import com.cobblemon.mod.common.util.toBlockPos
import com.cobblemon.mod.common.util.toVec3d
import kotlin.math.ceil
import kotlin.math.sqrt
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.Holder
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.ai.village.poi.PoiManager
import net.minecraft.world.entity.ai.village.poi.PoiType
import net.minecraft.world.level.block.Blocks
@@ -114,73 +112,6 @@ object LurePokeSnackDetector : SpawningInfluenceDetector {
}
}
fun attemptSafeMove2(level: ServerLevel, startPos: BlockPos, entity: PokemonEntity, ) {
val inWater = entity.isInWater
// Random offset in a cardinal direction (north, south, east, west)
val randomDirection = listOf(Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST).random()
val initialOffsetPos = startPos.relative(randomDirection)
// Variables to track the best (closest) safe position
var safePos: BlockPos? = null
var bestDistanceSq = Double.MAX_VALUE
val maxRadius = 10
// Search within a sphere around the initial offset position
for (dx in -maxRadius..maxRadius) {
for (dy in -maxRadius..maxRadius) {
for (dz in -maxRadius..maxRadius) {
val candidatePos = initialOffsetPos.offset(dx, dy, dz)
val distanceSq = startPos.distSqr(candidatePos)
// Check if within sphere radius
if (dx*dx + dy*dy + dz*dz <= maxRadius*maxRadius) {
// Check collision at candidate position
val currentBox = entity.boundingBox.move(
candidatePos.x - entity.x,
candidatePos.y - entity.y,
candidatePos.z - entity.z
)
if (level.noCollision(entity, currentBox)) {
val blockBelowPos = candidatePos.below()
val blockState = level.getBlockState(blockBelowPos)
val isWater = blockState.block == Blocks.WATER
if (inWater) {
if (isWater) {
if (distanceSq < bestDistanceSq) {
bestDistanceSq = distanceSq
safePos = candidatePos
}
}
} else {
if (!blockState.isAir) {
if (distanceSq < bestDistanceSq) {
bestDistanceSq = distanceSq
safePos = candidatePos
}
}
}
}
}
}
}
}
if (safePos != null) {
entity.moveTo(safePos.toVec3d())
PokeSnackBlockParticlesPacket(startPos, safePos).sendToPlayersAround(
startPos.x.toDouble(),
startPos.y.toDouble(),
startPos.z.toDouble(),
64.0,
level.dimension()
)
}
}
fun attemptSafeMove(level: ServerLevel, startPos: BlockPos, entity: PokemonEntity) {
val inWater = entity.isInWater
val maxDistance = 10 // maximum search radius
@@ -255,4 +186,4 @@ object LurePokeSnackDetector : SpawningInfluenceDetector {
}
override fun detectFromBlock(level: ServerLevel, pos: BlockPos, blockState: BlockState) = emptyList<SpawningZoneInfluence>()
}
}
@@ -161,6 +161,10 @@ open class PlayerPartyStore(
if (pokemon.interactionCooldowns.any()) {
pokemon.tickInteractionCooldown()
}
if (pokemon.entity?.passengers?.isNotEmpty() != true) {
pokemon.rideStamina += 0.1F // Recover all stamina in 10 seconds, as long as no one's on it
}
}
// Friendship
// ToDo expand this down the line just a very basic implementation for the first releases
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonRecipeTypes
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.cooking.Seasonings
import com.cobblemon.mod.common.api.cooking.getColourMixFromSeasonings
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
import com.cobblemon.mod.common.item.components.PotComponent
@@ -477,9 +478,10 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
}
override fun canPlaceItemThroughFace(index: Int, itemStack: ItemStack, direction: Direction?): Boolean {
return when (direction) {
Direction.UP -> SEASONING_SLOTS.contains(index)
else -> CRAFTING_GRID_SLOTS.contains(index)
return if(direction == Direction.UP && Seasonings.isSeasoning(itemStack)){
SEASONING_SLOTS.contains(index)
} else {
CRAFTING_GRID_SLOTS.contains(index)
}
}
@@ -29,7 +29,15 @@ import com.cobblemon.mod.common.client.gui.cookingpot.CookingPotScreen
import com.cobblemon.mod.common.client.particle.BedrockParticleOptionsRepository
import com.cobblemon.mod.common.client.render.ClientPlayerIcon
import com.cobblemon.mod.common.client.render.DeferredRenderer
import com.cobblemon.mod.common.client.render.block.*
import com.cobblemon.mod.common.client.render.block.BerryBlockRenderer
import com.cobblemon.mod.common.client.render.block.CampfireBlockEntityRenderer
import com.cobblemon.mod.common.client.render.block.DisplayCaseRenderer
import com.cobblemon.mod.common.client.render.block.FossilAnalyzerRenderer
import com.cobblemon.mod.common.client.render.block.GildedChestBlockRenderer
import com.cobblemon.mod.common.client.render.block.HealingMachineRenderer
import com.cobblemon.mod.common.client.render.block.LecternBlockEntityRenderer
import com.cobblemon.mod.common.client.render.block.PokeSnackBlockEntityRenderer
import com.cobblemon.mod.common.client.render.block.RestorationTankRenderer
import com.cobblemon.mod.common.client.render.boat.CobblemonBoatRenderer
import com.cobblemon.mod.common.client.render.color.AprijuiceItemColorProvider
import com.cobblemon.mod.common.client.render.color.PokeBaitItemColorProvider
@@ -42,7 +50,9 @@ import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererR
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.*
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.client.render.npc.NPCRenderer
import com.cobblemon.mod.common.client.render.pokeball.PokeBallRenderer
import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer
@@ -50,18 +60,22 @@ import com.cobblemon.mod.common.client.requests.ClientPlayerActionRequests
import com.cobblemon.mod.common.client.sound.BattleMusicController
import com.cobblemon.mod.common.client.sound.EntitySoundTracker
import com.cobblemon.mod.common.client.storage.ClientStorageManager
import com.cobblemon.mod.common.client.tooltips.*
import com.cobblemon.mod.common.client.tooltips.AprijuiceTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.CobblemonTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.FishingBaitTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.FishingRodTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.PokePuffTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.RecipeSeasoningAbsorbtionTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.SeasoningTooltipGenerator
import com.cobblemon.mod.common.client.tooltips.TooltipManager
import com.cobblemon.mod.common.client.trade.ClientTrade
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.item.food.SinisterTeaItem
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext
import com.cobblemon.mod.common.util.isLookingAt
import net.minecraft.client.Minecraft
import net.minecraft.client.color.block.BlockColor
import net.minecraft.client.color.item.ItemColor
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.MenuScreens
import net.minecraft.client.gui.screens.Screen
@@ -421,5 +435,4 @@ object CobblemonClient {
)
}
}
}
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.client.persisted.ClientPersistedData
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.CameraType
import net.minecraft.client.Minecraft
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.Entity
/**
* The purpose here is to keep track of the last camera type that was used for each riding behaviour or just
* the last overall, then change the camera type where necessary when mounting/dismounting or switching
* between different riding behaviours. This is dependent on a config option, but the general idea is we
* want the camera to be whatever the player feels most comfy with without them having to fiddle with it
* more than once.
*/
object MountedCameraTypeHandler {
var unmountedCameraType: CameraType = CameraType.FIRST_PERSON
fun handleMount(passenger: Entity, vehicle: PokemonEntity) {
val mc = Minecraft.getInstance()
val key = vehicle.ridingController?.context?.settings?.key
if (passenger != mc.player || key == null) {
return
}
unmountedCameraType = mc.options.cameraType
val data = ClientPersistedData.ridingPerspectives
if (Cobblemon.config.rememberRidingCamera) {
val lastCameraTypeForKey = data.perspectives[key]
if (lastCameraTypeForKey != null) {
mc.options.cameraType = lastCameraTypeForKey
}
}
}
fun handleDismount(passenger: Entity, vehicle: PokemonEntity) {
val mc = Minecraft.getInstance()
val key = vehicle.ridingController?.context?.settings?.key
if (passenger != mc.player || key == null) {
return
}
val currentCameraType = mc.options.cameraType
if (currentCameraType != unmountedCameraType) {
mc.options.cameraType = unmountedCameraType
}
val data = ClientPersistedData.ridingPerspectives
data.updatePerspective(key, currentCameraType)
}
fun handleTransition(fromKey: ResourceLocation, toKey: ResourceLocation) {
val mc = Minecraft.getInstance()
val currentCameraType = mc.options.cameraType
val data = ClientPersistedData.ridingPerspectives
data.updatePerspective(fromKey, currentCameraType)
if (Cobblemon.config.rememberRidingCamera) {
val lastCameraTypeForKey = data.perspectives[toKey]
if (lastCameraTypeForKey != null) {
mc.options.cameraType = lastCameraTypeForKey
}
}
}
}
@@ -12,7 +12,9 @@ import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
import com.cobblemon.mod.common.config.CobblemonConfig
import com.cobblemon.mod.common.util.asTranslated
import com.cobblemon.mod.common.util.ifServer
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.runOnServer
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.components.Button
import net.minecraft.client.gui.components.EditBox
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.client.gui.pokedex.widgets
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.gui.ParentWidget
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
@@ -25,6 +25,8 @@ import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.features.FriendshipFeatureRenderer
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.features.FullnessFeatureRenderer
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.pokemon.EVs
import com.cobblemon.mod.common.pokemon.IVs
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
@@ -74,6 +76,7 @@ class StatWidget(
private val statsBaseResource = cobblemonResource("textures/gui/summary/summary_stats_chart_base.png")
private val statsChartResource = cobblemonResource("textures/gui/summary/summary_stats_chart.png")
private val statsChartPentagonResource = cobblemonResource("textures/gui/summary/summary_stats_chart_pentagon.png")
private val statsChartPentagonHighlightResource = cobblemonResource("textures/gui/summary/summary_stats_chart_pentagon_highlight.png")
private val statsOtherBaseResource = cobblemonResource("textures/gui/summary/summary_stats_other_base.png")
private val statsOtherSidebarsResource = cobblemonResource("textures/gui/summary/summary_stats_other_sidebars.png")
private val statsOtherSidebarArrowLeft = cobblemonResource("textures/gui/summary/summary_stats_other_sidebar_arrow_left.png")
@@ -290,33 +293,34 @@ class StatWidget(
}
} else {
if (renderPentagonStats) {
blitk(
matrixStack = matrices,
texture = statsChartPentagonResource,
x= (x + 20.5) / SCALE,
y = (y + 22) / SCALE,
width = 186,
height = 176,
scale = SCALE
)
pokemon.form.riding.behaviours?.let {
val behaviours = it.entries.toList()
val selectedBehaviour = behaviours[rideBehaviourIndex]
val canSwitchStyle = behaviours.size > 1 && centerHovered(pMouseX, pMouseY)
blitk(
matrixStack = matrices,
texture = if (canSwitchStyle) statsChartPentagonHighlightResource else statsChartPentagonResource,
x= (x + 20.5) / SCALE,
y = (y + 22) / SCALE,
width = 186,
height = 176,
scale = SCALE
)
val pentagonColour = when (selectedBehaviour.key) {
RidingStyle.AIR -> {
if (behaviours.size > 1 && centerHovered(pMouseX, pMouseY))
if (canSwitchStyle)
Vector3f(70F/255F, 235F/225F, 195F/255F)
else Vector3f(40F/255F, 205F/255F, 165F/255F)
}
RidingStyle.LIQUID -> {
if (behaviours.size > 1 && centerHovered(pMouseX, pMouseY))
if (canSwitchStyle)
Vector3f(95F/255F, 165F/255F, 1F)
else Vector3f(65F/255F, 135F/255F, 1F)
}
else -> {
if (behaviours.size > 1 && centerHovered(pMouseX, pMouseY))
if (canSwitchStyle)
Vector3f(1F, 195F/255F, 30F/255F)
else Vector3f(1F, 165F/255F, 0F)
}
@@ -353,8 +357,8 @@ class StatWidget(
context = context,
labels = RidingStat.entries.toList().map { stat ->
if (statLabelsHovered(pentagonVerticesOffset, pMouseX, pMouseY))
"${floor((pokemon.getRideStat(selectedBehaviour.key, stat) / (selectedBehaviour.value.stats[stat]?.endInclusive ?: 1)) * 100)}%".text()
else floor(pokemon.getRideStat(selectedBehaviour.key, stat)).toString().text()
"+${floor(pokemon.getRideBoost(stat) / pokemon.getMaxRideBoost(stat) * 100)}%".text()
else floor(pokemon.getRideStat(selectedBehaviour.key, stat)).toString().text()
},
verticesOffset = pentagonVerticesOffset,
offsetY = 5.5
@@ -389,7 +393,7 @@ class StatWidget(
colour = Vector3f(216F/255, 100F/255, 1F)
)
EV -> drawStatPolygon(
statLabels.values.map { (pokemon.evs[it]?.toFloat() ?: 0F) / 252F },
statLabels.values.map { (pokemon.evs[it]?.toFloat() ?: 0F) / EVs.MAX_STAT_VALUE.toFloat() },
colour = Vector3f(1F, 1F, 100F/255F)
)
}
@@ -403,9 +407,9 @@ class StatWidget(
"${
if (pokemon.ivs.isHyperTrained(stat.value)) "${pokemon.ivs[stat.value]} (${pokemon.ivs.hyperTrainedIVs[stat.value]})"
else pokemon.ivs[stat.value].toString()
}/31".text()
}/${IVs.MAX_VALUE}".text()
}
EV -> "${pokemon.evs.getOrDefault(stat.value)}/252".text()
EV -> "${pokemon.evs.getOrDefault(stat.value)}/${EVs.MAX_STAT_VALUE}".text()
else -> stat.key
}
} else { stat.key }
@@ -427,8 +431,7 @@ class StatWidget(
labelsHovered
),
verticesOffset = hexagonVerticesOffset,
offsetY = 5.5,
enableColour = true
offsetY = 5.5
)
// Nature-modified Stat Icons
@@ -491,14 +494,14 @@ class StatWidget(
STATS -> (if (stat == Stats.HP) "${pokemon.currentHealth} / ${pokemon.maxHealth}" else pokemon.getStat(stat).toString()).text()
IV -> {
(if (asPercent) {
"${floor((((if (pokemon.ivs.isHyperTrained(stat)) pokemon.ivs.hyperTrainedIVs[stat] else pokemon.ivs[stat]) ?: 0) / 31.0) * 100)}%"
"${floor((((if (pokemon.ivs.isHyperTrained(stat)) pokemon.ivs.hyperTrainedIVs[stat] else pokemon.ivs[stat]) ?: 0) / IVs.MAX_VALUE.toDouble()) * 100)}%"
} else {
if (pokemon.ivs.isHyperTrained(stat)) "${pokemon.ivs[stat]} (${pokemon.ivs.hyperTrainedIVs[stat]})"
else pokemon.ivs[stat].toString()
}).text()
}
EV -> {
(if (asPercent) "${floor((pokemon.evs.getOrDefault(stat) / 252.0) * 100)}%"
(if (asPercent) "${floor((pokemon.evs.getOrDefault(stat) / EVs.MAX_STAT_VALUE.toDouble()) * 100)}%"
else pokemon.evs.getOrDefault(stat).toString()).text()
}
else -> "0".text()
@@ -559,7 +562,9 @@ class StatWidget(
}
private fun centerHovered(pMouseX: Number, pMouseY: Number): Boolean {
return (pMouseX.toInt() in (x + 44)..(x + 90)) && (pMouseY.toInt() in (y + 47)..(y + 93))
val centerX = x + (WIDTH / 2)
val centerY = y + (HEIGHT / 2)
return (pMouseX.toInt() in (centerX - 30)..(centerX + 30)) && (pMouseY.toInt() in (centerY - 30)..(centerY + 30))
}
private fun statLabelsHovered(labelOffsets: List<Pair<Double, Double>>, mouseX: Int, mouseY: Int): Boolean {
@@ -0,0 +1,33 @@
/*
* 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.net.data
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
import com.cobblemon.mod.common.net.messages.client.data.RideSettingsSyncPacket
import net.minecraft.client.Minecraft
object RideSettingsSyncHandler : ClientNetworkPacketHandler<RideSettingsSyncPacket> {
override fun handle(packet: RideSettingsSyncPacket, client: Minecraft) {
CobblemonRideSettings.bird = packet.bird
CobblemonRideSettings.glider = packet.glider
CobblemonRideSettings.helicopter = packet.helicopter
CobblemonRideSettings.hover = packet.hover
CobblemonRideSettings.jet = packet.jet
CobblemonRideSettings.rocket = packet.rocket
CobblemonRideSettings.horse = packet.horse
CobblemonRideSettings.minekart = packet.minekart
CobblemonRideSettings.vehicle = packet.vehicle
CobblemonRideSettings.boat = packet.boat
CobblemonRideSettings.burst = packet.burst
CobblemonRideSettings.dolphin = packet.dolphin
}
}
@@ -0,0 +1,70 @@
/*
* 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.persisted
import com.cobblemon.mod.common.config.CobblemonConfig
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.FileInputStream
import java.io.FileWriter
import java.io.InputStreamReader
import java.nio.file.Paths
import kotlin.io.path.exists
import net.minecraft.client.CameraType
import net.minecraft.resources.ResourceLocation
object ClientPersistedData {
val gson = CobblemonConfig.GSON
val snapshotsPath = Paths.get("cobblemon").resolve("snapshots.json")
val ridingPerspectivesPath = Paths.get("cobblemon").resolve("riding_perspectives.json")
var ridingPerspectives: RidingPerspectiveData = readRidingPerspectivesData() ?: RidingPerspectiveData()
fun readSnapshotsData() : SnapshotAcknowledgementData? {
if (snapshotsPath.exists()) {
BufferedReader(InputStreamReader(FileInputStream(snapshotsPath.toFile()))).use { reader ->
return gson.fromJson(reader, SnapshotAcknowledgementData::class.java)
}
}
return null
}
fun writeSnapshotsData(data: SnapshotAcknowledgementData) {
snapshotsPath.toFile().parentFile.mkdirs()
BufferedWriter(FileWriter(snapshotsPath.toFile())).use { writer -> gson.toJson(data, writer) }
}
fun readRidingPerspectivesData() : RidingPerspectiveData? {
if (ridingPerspectivesPath.exists()) {
BufferedReader(InputStreamReader(FileInputStream(ridingPerspectivesPath.toFile()))).use { reader ->
return gson.fromJson(reader, RidingPerspectiveData::class.java)
}
}
return null
}
fun saveRidingPerspectivesData() {
ridingPerspectivesPath.toFile().parentFile.mkdirs()
BufferedWriter(FileWriter(ridingPerspectivesPath.toFile())).use { writer -> gson.toJson(ridingPerspectives, writer) }
}
data class SnapshotAcknowledgementData(val version: String, val dontShowAgain: Boolean)
data class RidingPerspectiveData(
val perspectives: MutableMap<ResourceLocation, CameraType> = mutableMapOf()
) {
fun updatePerspective(key: ResourceLocation, cameraType: CameraType) {
perspectives[key] = cameraType
saveRidingPerspectivesData()
}
}
}
@@ -17,10 +17,12 @@ import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import com.mojang.blaze3d.platform.Lighting
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexMultiConsumer
import net.minecraft.client.renderer.LightTexture
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.core.component.DataComponents
import net.minecraft.world.item.ItemDisplayContext
import net.minecraft.world.item.ItemStack
import org.joml.Quaternionf
@@ -46,8 +48,6 @@ class PokemonItemRenderer : CobblemonBuiltinItemRenderer {
context.put(RenderContext.POSABLE_STATE, state)
state.currentModel = model
val renderLayer = RenderType.entityCutout(VaryingModelRepository.getTexture(species.resourceIdentifier, state))
val transformations = positions[mode]!!
if (mode == ItemDisplayContext.GUI) {
@@ -64,7 +64,19 @@ class PokemonItemRenderer : CobblemonBuiltinItemRenderer {
val rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(transformations.rotation.x, transformations.rotation.y, transformations.rotation.z))
matrices.mulPose(rotation)
rotation.conjugate()
val vertexConsumer: VertexConsumer = vertexConsumers.getBuffer(renderLayer)
val renderLayer = RenderType.entityCutout(VaryingModelRepository.getTexture(species.resourceIdentifier, state))
val isEnchanted = stack.get(DataComponents.ENCHANTMENTS)?.isEmpty == false
val vertexConsumer: VertexConsumer =
if (isEnchanted) {
VertexMultiConsumer.create(
vertexConsumers.getBuffer(RenderType.entityGlintDirect()),
vertexConsumers.getBuffer(renderLayer),
)
} else {
vertexConsumers.getBuffer(renderLayer)
}
matrices.pushPose()
val packedLight = if (mode == ItemDisplayContext.GUI) {
LightTexture.pack(13, 13)
@@ -267,7 +267,7 @@ class TexturedModel {
var counter = 0
subParts.forEachIndexed { index, part ->
parts[bone.name]!!.addOrReplaceChild(
bone.name + counter++.toString(),
"%" + bone.name + "%" + counter++.toString(),
part,
modelTransforms[index]
)
@@ -1,67 +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 BeheeyemModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("beheeyem")
override val head = getPart("head")
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 = 3.0F
override var portraitTranslation = Vec3(-0.34, -0.8, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("beheeyem", "cry") }
override fun registerPoses() {
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("beheeyem", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
animations = arrayOf(
singleBoneLook(),
bedrock("beheeyem", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
animations = arrayOf(
singleBoneLook(),
bedrock("beheeyem", "ground_walk")
)
)
}
}
@@ -1,94 +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.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ChandelureModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("chandelure")
override val head = getPart("head")
override var portraitScale = 1.85F
override var portraitTranslation = Vec3(-0.3, -0.19, 0.0)
override var profileScale = 0.81F
override var profileTranslation = Vec3(0.0, 0.68, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var hover: CobblemonPose
lateinit var flying: CobblemonPose
lateinit var battle_idle: CobblemonPose
lateinit var sleep: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("chandelure", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("chandelure", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES - PoseType.HOVER,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
bedrock("chandelure", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("chandelure", "ground_walk")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("chandelure", "air_idle")
)
)
flying = registerPose(
poseName = "flying",
poseType = PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("chandelure", "air_fly")
)
)
battle_idle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("chandelure", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("chandelure", "faint") else null
}
@@ -1,113 +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.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
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.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.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ElgyemModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("elgyem")
override val head = getPart("head")
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.5F
override var portraitTranslation = Vec3(-0.2, -0.8, 0.0)
override var profileScale = 0.85F
override var profileTranslation = Vec3(0.0, 0.5, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var battleidle: Pose
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
override val cryAnimation = CryProvider { bedrockStateful("elgyem", "cry") }
val shoulderOffset = 5.6
override fun registerPoses() {
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("elgyem", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("elgyem", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
animations = arrayOf(
singleBoneLook(),
bedrock("elgyem", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("elgyem", "battle_idle")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
//quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("elgyem", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
//quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("elgyem", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, battleidle, sleep)) bedrockStateful("elgyem", "faint") else null
}
@@ -1,102 +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.pokemon.PokemonPosableModel
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.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class LampentModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("lampent")
override val head = getPart("head")
override var portraitScale = 2.2F
override var portraitTranslation = Vec3(-0.19, -0.17, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.7, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var hover: CobblemonPose
lateinit var flying: CobblemonPose
lateinit var battle_idle: CobblemonPose
lateinit var sleep: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("lampent", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("lampent", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(
bedrock("lampent", "sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES - PoseType.HOVER,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
bedrock("lampent", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("lampent", "ground_walk")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("lampent", "air_idle")
)
)
flying = registerPose(
poseName = "flying",
poseType = PoseType.FLY,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("lampent", "air_fly")
)
)
battle_idle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("lampent", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("lampent", "faint") else null
}
@@ -1,110 +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.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
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.pose.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class LitwickModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("litwick")
override val head = getPart("head")
override var portraitScale = 2.33F
override var portraitTranslation = Vec3(0.01, -1.9, 0.0)
override var profileScale = 0.86F
override var profileTranslation = Vec3(0.0, 0.44, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
lateinit var sleep: CobblemonPose
lateinit var battle_idle: CobblemonPose
lateinit var shoulderLeft: CobblemonPose
lateinit var shoulderRight: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("litwick", "cry") }
val shoulderOffset = 5.5
val wax = getPart("wax_trail")
override fun registerPoses() {
val blink = quirk { bedrockStateful("litwick", "blink") }
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
animations = arrayOf(
bedrock("litwick", "sleep")
)
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
condition = { !it.isBattling },
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("litwick", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("litwick", "ground_walk")
)
)
battle_idle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("litwick", "battle_idle")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("litwick", "ground_idle")
),
transformedParts = arrayOf(
wax.createTransformation().withVisibility(visibility = false)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("litwick", "ground_idle")
),
transformedParts = arrayOf(
wax.createTransformation().withVisibility(visibility = false)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("litwick", "faint") else null
}
@@ -361,8 +361,6 @@ object VaryingModelRepository {
inbuilt("chespin", :: ChespinModel)
inbuilt("quilladin", :: QuilladinModel)
inbuilt("chesnaught", :: ChesnaughtModel)
inbuilt("elgyem", :: ElgyemModel)
inbuilt("beheeyem", :: BeheeyemModel)
inbuilt("pineco", :: PinecoModel)
inbuilt("forretress", :: ForretressModel)
inbuilt("lotad", :: LotadModel)
@@ -554,9 +552,6 @@ object VaryingModelRepository {
inbuilt("gurdurr", ::GurdurrModel)
inbuilt("conkeldurr", ::ConkeldurrModel)
inbuilt("clodsire", ::ClodsireModel)
inbuilt("litwick", ::LitwickModel)
inbuilt("lampent", ::LampentModel)
inbuilt("chandelure", ::ChandelureModel)
inbuilt("gimmighoulchest", ::GimmighoulChestModel)
inbuilt("drifloon", ::DrifloonModel)
inbuilt("lileep", ::LileepModel)
@@ -1,43 +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.snapshots
import com.cobblemon.mod.common.config.CobblemonConfig
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.FileInputStream
import java.io.FileWriter
import java.io.InputStreamReader
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.exists
object SnapshotAcknowledgementReader {
val gson = CobblemonConfig.GSON
val target: Path = Paths.get("cobblemon").resolve("snapshots.json")
fun read() : SnapshotAcknowledgementData? {
if (target.exists()) {
BufferedReader(InputStreamReader(FileInputStream(target.toFile()))).use { reader ->
return gson.fromJson(reader, SnapshotAcknowledgementData::class.java)
}
}
return null
}
fun write(data: SnapshotAcknowledgementData) {
target.toFile().parentFile.mkdirs()
BufferedWriter(FileWriter(target.toFile())).use { writer -> gson.toJson(data, writer) }
}
}
data class SnapshotAcknowledgementData(val version: String, val dontShowAgain: Boolean)
@@ -9,34 +9,60 @@
package com.cobblemon.mod.common.command
import com.cobblemon.mod.common.api.permission.CobblemonPermissions
import com.cobblemon.mod.common.api.text.green
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.util.commandLang
import com.cobblemon.mod.common.util.requiresWithPermission
import com.cobblemon.mod.common.util.permission
import com.cobblemon.mod.common.util.traceFirstEntityCollision
import com.mojang.brigadier.Command
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.context.CommandContext
import net.minecraft.commands.CommandSourceStack
import net.minecraft.commands.Commands
import net.minecraft.server.level.ServerPlayer
import net.minecraft.commands.arguments.EntityArgument
import net.minecraft.world.entity.Entity
object NPCDeleteCommand {
fun register(dispatcher : CommandDispatcher<CommandSourceStack>) {
dispatcher.register(
Commands.literal("npcdelete")
.requiresWithPermission(CobblemonPermissions.NPC_DELETE) { it.player != null }
.executes { execute(it, it.source.playerOrException) })
.permission(CobblemonPermissions.NPC_DELETE)
.then(
Commands.argument("target", EntityArgument.entity())
.executes {context ->
val source = context.source
val entity = EntityArgument.getEntity(context, "target")
execute(entity, source)
}
)
.executes {context ->
val source = context.source
val player = source.player
if (player == null) {
source.sendSystemMessage(commandLang("npcdelete.not_player").red())
return@executes 0
}
val targetEntity = player.traceFirstEntityCollision(entityClass = NPCEntity::class.java)
if (targetEntity == null) {
player.sendSystemMessage(commandLang("npcedit.non_npc").red())
return@executes 0
}
execute(targetEntity, source)
}
)
}
private fun execute(context: CommandContext<CommandSourceStack>, player: ServerPlayer) : Int {
val targetEntity = player.traceFirstEntityCollision(entityClass = NPCEntity::class.java)
if (targetEntity == null) {
player.sendSystemMessage(commandLang("npcedit.non_npc").red())
private fun execute(entity: Entity, source: CommandSourceStack) : Int {
if(entity !is NPCEntity){
source.sendSystemMessage(commandLang("npcedit.non_npc").red())
return 0
}
targetEntity.discard()
entity.discard()
source.sendSystemMessage(commandLang("npcdelete.deleted", entity.name.string).green())
return Command.SINGLE_SUCCESS
}
}
@@ -15,11 +15,13 @@ import com.cobblemon.mod.common.client.gui.portrait.PortraitStyle
import com.cobblemon.mod.common.config.constraint.IntConstraint
import com.cobblemon.mod.common.pokeball.catching.calculators.CobblemonCaptureCalculator
import com.cobblemon.mod.common.util.adapters.CaptureCalculatorAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.IntRangeAdapter
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import net.minecraft.resources.ResourceLocation
class CobblemonConfig {
companion object {
@@ -29,6 +31,7 @@ class CobblemonConfig {
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
.registerTypeAdapter(ItemDropMethod::class.java, ItemDropMethod.adapter)
.registerTypeAdapter(CaptureCalculator::class.java, CaptureCalculatorAdapter)
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.create()
}
@@ -300,6 +303,12 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Riding, lang = "display_controls_duration_seconds")
var displayControlSeconds = 3
@CobblemonConfigField(Category.Riding, lang = "infinite_ride_stamina")
var infiniteRideStamina = false
@CobblemonConfigField(Category.Riding, lang = "remember_riding_camera")
var rememberRidingCamera = true
@CobblemonConfigField(Category.Debug, lang = "enable_debug_keys")
var enableDebugKeys = true
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.CobblemonBehaviours
import com.cobblemon.mod.common.CobblemonCallbacks
import com.cobblemon.mod.common.CobblemonCosmeticItems
import com.cobblemon.mod.common.CobblemonMechanics
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.CobblemonUnlockableWallpapers
import com.cobblemon.mod.common.api.abilities.Abilities
import com.cobblemon.mod.common.api.berry.Berries
@@ -109,6 +110,7 @@ object CobblemonDataProvider : DataProvider {
this.register(Seasonings, reloadable = false)
this.register(PokemonInteractions, reloadable = false)
this.register(SpawnBaitEffects, reloadable = false)
this.register(CobblemonRideSettings, reloadable = true)
SpawnBait.Effects.setupEffects()
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe {
@@ -132,7 +132,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
val f = abs(mob.z - targetVec3d.z)
val closeEnough = d < maxDistanceToWaypoint.toDouble()
&& f < this.maxDistanceToWaypoint.toDouble()
&& e < (if (currentNode.type in verticallyPreciseNodeTypes && (mob.isUnderWater || pather.isFlying())) 1.0 else 1.0).toDouble()
&& e < (if (currentNode.type in verticallyPreciseNodeTypes && (mob.isUnderWater || pather.isFlying())) maxDistanceToWaypoint else 1.0).toDouble()
// Corner cutting is commented out because it makes pokemon and NPCs 'cut' the corner and fall into water or lava
if (closeEnough) {// || mob.navigation.canCutCorner(path!!.nextNode.type) && shouldTargetNextNodeInDirection(vec3d)) {
@@ -73,6 +73,7 @@ import com.cobblemon.mod.common.battles.BattleBuilder
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.SuccessfulBattleStart
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
import com.cobblemon.mod.common.client.MountedCameraTypeHandler
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.entity.BehaviourEditingTracker
import com.cobblemon.mod.common.entity.EntityCallbacks
@@ -216,6 +217,7 @@ open class PokemonEntity(
@JvmStatic val EVOLUTION_STARTED = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.BOOLEAN)
@JvmStatic var SHOWN_HELD_ITEM = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.ITEM_STACK)
@JvmStatic var RIDE_BOOSTS = SynchedEntityData.defineId(PokemonEntity::class.java, RideBoostsDataSerializer)
@JvmStatic var RIDE_STAMINA = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.FLOAT)
const val BATTLE_LOCK = "battle"
const val EVOLUTION_LOCK = "evolving"
@@ -460,6 +462,7 @@ open class PokemonEntity(
builder.define(EVOLUTION_STARTED, false)
builder.define(SHOWN_HELD_ITEM, ItemStack.EMPTY)
builder.define(RIDE_BOOSTS, emptyMap())
builder.define(RIDE_STAMINA, 1F)
}
override fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {
@@ -537,8 +540,12 @@ open class PokemonEntity(
if (passengerIndex != -1) {
occupiedSeats[passengerIndex] = null
}
if (level().isClientSide) {
MountedCameraTypeHandler.handleDismount(passenger, this)
}
super.removePassenger(passenger)
if (passengers.isEmpty()) {
ifRidingAvailable { _, _, state -> pokemon.rideStamina = state.stamina.get() }
ridingController?.context?.state?.reset()
ridingAnimationData.clear()
}
@@ -1455,7 +1462,7 @@ open class PokemonEntity(
fun tryRidingPokemon(player: ServerPlayer): Boolean {
val event = RidePokemonEvent.Pre(player, this)
CobblemonEvents.RIDE_EVENT_PRE.post(event)
if(!event.isCanceled) {
if (!event.isCanceled) {
player.startRiding(this)
CobblemonEvents.RIDE_EVENT_POST.post(RidePokemonEvent.Post(player, this))
return true
@@ -2098,16 +2105,37 @@ open class PokemonEntity(
public override fun addPassenger(passenger: Entity) {
if (passenger is ServerPlayer) {
// Recall all the rest of the player's party pokes
passenger.party()
.mapNotNull { it.entity }
.filter { it != this }
.forEach { it.recallWithAnimation() }
// Driver is hopping on, figure out the stamina situation
if (passengers.isEmpty()) {
CobblemonEvents.RIDE_EVENT_APPLY_STAMINA.post(
RidePokemonEvent.ApplyStamina(
player = passenger,
pokemon = this,
rideStamina = if (Cobblemon.config.infiniteRideStamina) -1F else entityData.get(RIDE_STAMINA)
),
then = { event -> entityData.set(RIDE_STAMINA, event.rideStamina) }
)
}
} else if (level().isClientSide) {
MountedCameraTypeHandler.handleMount(passenger, this)
}
val passengerIndex = occupiedSeats.indexOfFirst { it == null }
if (passengerIndex != -1) {
occupiedSeats[passengerIndex] = passenger
}
super.addPassenger(passenger)
if (passengers.size == 1) {
// Someone just started riding, fill in the stamina value! Gets run from both sides.
ifRidingAvailable { _, _, state ->
state.stamina.set(entityData.get(RIDE_STAMINA))
}
}
}
fun getIsJumping() = jumping
@@ -2137,6 +2165,9 @@ open class PokemonEntity(
super.tickRidden(driver, movementInput)
ifRidingAvailable { behaviour, settings, state ->
behaviour.tick(settings, state, this, driver, movementInput)
if (entityData.get(RIDE_STAMINA) == -1F) {
state.stamina.set(1F, forced = true)
}
if (!this.level().isClientSide) {
val pose = behaviour.pose(settings, state, this)
@@ -235,6 +235,9 @@ class PokemonServerDelegate : PokemonSideDelegate {
entity.entityData.set(PokemonEntity.FRIENDSHIP, entity.pokemon.friendship)
entity.entityData.set(PokemonEntity.CAUGHT_BALL, trackedBall)
if (entity.pokemon.rideStamina != entity.entityData.get(PokemonEntity.RIDE_STAMINA) && entity.passengers.isEmpty()) {
entity.entityData.set(PokemonEntity.RIDE_STAMINA, entity.pokemon.rideStamina)
}
val currentRideBoosts = entity.entityData.get(PokemonEntity.RIDE_BOOSTS)
val newRideBoosts = entity.pokemon.getRideBoosts()
@@ -80,6 +80,7 @@ object CallbackHandler {
CobblemonEvents.TRADE_EVENT_PRE.subscribe { CobblemonCallbacks.run(cobblemonResource("trade_event_pre"), it.context, it.functions) }
CobblemonEvents.TRADE_EVENT_POST.subscribe { CobblemonCallbacks.run(cobblemonResource("trade_event_post"), it.context) }
CobblemonEvents.RIDE_EVENT_PRE.subscribe { CobblemonCallbacks.run(cobblemonResource("ride_event_pre"), it.context, it.functions) }
CobblemonEvents.RIDE_EVENT_APPLY_STAMINA.subscribe { CobblemonCallbacks.run(cobblemonResource("ride_event_apply_stamina"), it.context, it.functions) }
CobblemonEvents.RIDE_EVENT_POST.subscribe { CobblemonCallbacks.run(cobblemonResource("ride_event_post"), it.context) }
CobblemonEvents.WALLPAPER_UNLOCKED_EVENT.subscribe { CobblemonCallbacks.run(cobblemonResource("wallpaper_unlocked"), it.context, it.functions) }
CobblemonEvents.CHANGE_PC_BOX_WALLPAPER_EVENT_PRE.subscribe { CobblemonCallbacks.run(cobblemonResource("change_pc_box_wallpaper_pre"), it.context, it.functions) }
@@ -102,13 +102,11 @@ class AprijuiceItem(val type: Apricorn): CobblemonItem(Properties().stacksTo(16)
if (!canUseOnPokemon(stack, pokemon)) {
return InteractionResultHolder.fail(stack)
}
val boosts = getBoosts(stack, pokemon)
// Feed the Pokémon 1 fullness point
pokemon.feedPokemon(1)
boosts.forEach { (stat, value) ->
pokemon.addRideBoost(stat, value)
}
pokemon.feedPokemon(1)
val boosts = getBoosts(stack, pokemon)
pokemon.addRideBoosts(boosts)
stack.consume(1, player)
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.item
import com.cobblemon.mod.common.api.item.PokemonSelectingItem
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundEvent
@@ -30,35 +29,37 @@ class RegionalFoodItem(properties: Properties) : Item(properties), PokemonSelect
override fun use(world: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
val stack = player.getItemInHand(hand)
// Allow eating normally if player needs food OR in creative
if (player !is ServerPlayer) {
return InteractionResultHolder.pass(stack);
}
// Prioritizes healing pokémon with the item
val superInteractionResult = super<PokemonSelectingItem>.use(player, stack)
if (superInteractionResult.result != InteractionResult.PASS) {
return superInteractionResult
}
// Otherwise allow eating normally if player needs food OR in creative
if (player.foodData.needsFood() || player.isCreative) {
player.startUsingItem(hand)
return InteractionResultHolder.consume(stack)
}
return InteractionResultHolder.fail(stack)
return InteractionResultHolder.pass(stack)
}
override fun interactLivingEntity(stack: ItemStack, player: Player, target: LivingEntity, hand: InteractionHand): InteractionResult {
if (player.level().isClientSide) return InteractionResult.PASS
if (player is ServerPlayer && target is PokemonEntity) {
val pokemon = target.pokemon
if (pokemon.status != null) {
return InteractionResult.SUCCESS
}
}
return InteractionResult.PASS
}
override fun applyToPokemon(player: ServerPlayer, stack: ItemStack, pokemon: Pokemon): InteractionResultHolder<ItemStack> {
override fun applyToPokemon(
player: ServerPlayer,
stack: ItemStack,
pokemon: Pokemon
): InteractionResultHolder<ItemStack> {
if (pokemon.status != null) {
pokemon.status = null
pokemon.entity?.playSound(SoundEvents.GENERIC_EAT, 1F, 1F)
stack.consume(1, player)
return InteractionResultHolder.success(stack)
}
return InteractionResultHolder.fail(stack)
}
@@ -0,0 +1,93 @@
/*
* 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.net.messages.client.data
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.riding.behaviour.types.air.BirdSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.GliderSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.air.HelicopterSettings
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.land.HorseSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.MinekartSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.land.VehicleSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.BoatSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.BurstSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.DolphinSettings
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
/**
* Synchronizes the [com.cobblemon.mod.common.CobblemonRideSettings] registry.
*/
class RideSettingsSyncPacket(
val bird: BirdSettings,
val glider: GliderSettings,
val helicopter: HelicopterSettings,
val hover: HoverSettings,
val jet: JetSettings,
val rocket: RocketSettings,
val horse: HorseSettings,
val minekart: MinekartSettings,
val vehicle: VehicleSettings,
val boat: BoatSettings,
val burst: BurstSettings,
val dolphin: DolphinSettings
) : NetworkPacket<RideSettingsSyncPacket> {
override val id = ID
override fun encode(buffer: RegistryFriendlyByteBuf) {
bird.encode(buffer)
glider.encode(buffer)
helicopter.encode(buffer)
hover.encode(buffer)
jet.encode(buffer)
rocket.encode(buffer)
horse.encode(buffer)
minekart.encode(buffer)
vehicle.encode(buffer)
boat.encode(buffer)
burst.encode(buffer)
dolphin.encode(buffer)
}
companion object {
val ID = cobblemonResource("mechanics_sync")
fun decode(buffer: RegistryFriendlyByteBuf): RideSettingsSyncPacket {
return RideSettingsSyncPacket(
bird = BirdSettings(),
glider = GliderSettings(),
helicopter = HelicopterSettings(),
hover = HoverSettings(),
jet = JetSettings(),
rocket = RocketSettings(),
horse = HorseSettings(),
minekart = MinekartSettings(),
vehicle = VehicleSettings(),
boat = BoatSettings(),
burst = BurstSettings(),
dolphin = DolphinSettings()
).apply {
bird.decode(buffer)
glider.decode(buffer)
helicopter.decode(buffer)
hover.decode(buffer)
jet.decode(buffer)
rocket.decode(buffer)
horse.decode(buffer)
minekart.decode(buffer)
vehicle.decode(buffer)
boat.decode(buffer)
burst.decode(buffer)
dolphin.decode(buffer)
}
}
}
}
@@ -0,0 +1,39 @@
/*
* 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.net.messages.client.pokemon.update
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.network.RegistryFriendlyByteBuf
/**
* Packet sent when the tracked stamina on Pokémon is updated. This is not the value that's
* actively controlling riding but rather the tracking property which is put into the riding
* state when the Pokémon is mounted.
*/
class RideStaminaUpdatePacket(pokemon: () -> Pokemon?, value: Float) : SingleUpdatePacket<Float, RideStaminaUpdatePacket>(pokemon, value) {
companion object {
val ID = com.cobblemon.mod.common.util.cobblemonResource("ride_stamina_update")
fun decode(buffer: RegistryFriendlyByteBuf): RideStaminaUpdatePacket {
val pokemon = decodePokemon(buffer)
val value = buffer.readFloat()
return RideStaminaUpdatePacket(pokemon, value)
}
}
override fun set(pokemon: Pokemon, value: Float) {
Cobblemon.LOGGER.info("Updating client with $value")
pokemon.rideStamina = value
}
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeFloat(this.value)
}
}
@@ -17,14 +17,22 @@ import com.cobblemon.mod.common.entity.PlatformType
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.util.*
import net.minecraft.client.multiplayer.ClientLevel
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.readText
import com.cobblemon.mod.common.util.writeEnumConstant
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.writeString
import com.cobblemon.mod.common.util.writeText
import java.util.UUID
import net.minecraft.world.entity.Entity
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.chat.MutableComponent
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.Entity
class SpawnPokemonPacket(
var ownerId: UUID?,
@@ -52,38 +60,40 @@ class SpawnPokemonPacket(
var passengers: IntArray,
var tickSpawned: Int,
var rideBoosts: Map<RidingStat, Float>,
var rideStamina: Float,
vanillaSpawnPacket: ClientboundAddEntityPacket,
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
override val id: ResourceLocation = ID
constructor(entity: PokemonEntity, vanillaSpawnPacket: ClientboundAddEntityPacket) : this(
entity.ownerUUID,
entity.pokemon.uuid,
entity.pokemon.scaleModifier,
entity.exposedSpecies.resourceIdentifier,
entity.pokemon.gender,
entity.pokemon.shiny,
entity.exposedForm.formOnlyShowdownId(),
entity.exposedAspects,
entity.battleId,
entity.phasingTargetId,
entity.beamMode.toByte(),
entity.platform,
entity.pokemon.nickname,
entity.pokemon.activeMark?.identifier,
if (Cobblemon.config.displayEntityLevelLabel) entity.entityData.get(PokemonEntity.LABEL_LEVEL) else -1,
entity.entityData.get(PokemonEntity.POSE_TYPE),
entity.entityData.get(PokemonEntity.UNBATTLEABLE),
entity.entityData.get(PokemonEntity.HIDE_LABEL),
entity.exposedBall.name,
entity.entityData.get(PokemonEntity.SPAWN_DIRECTION),
entity.entityData.get(PokemonEntity.FRIENDSHIP),
entity.entityData.get(PokemonEntity.FREEZE_FRAME),
entity.passengers.map { it.id }.toIntArray(),
entity.tickCount,
entity.entityData.get(PokemonEntity.RIDE_BOOSTS),
vanillaSpawnPacket
entity.ownerUUID,
entity.pokemon.uuid,
entity.pokemon.scaleModifier,
entity.exposedSpecies.resourceIdentifier,
entity.pokemon.gender,
entity.pokemon.shiny,
entity.exposedForm.formOnlyShowdownId(),
entity.exposedAspects,
entity.battleId,
entity.phasingTargetId,
entity.beamMode.toByte(),
entity.platform,
entity.pokemon.nickname,
entity.pokemon.activeMark?.identifier,
if (Cobblemon.config.displayEntityLevelLabel) entity.entityData.get(PokemonEntity.LABEL_LEVEL) else -1,
entity.entityData.get(PokemonEntity.POSE_TYPE),
entity.entityData.get(PokemonEntity.UNBATTLEABLE),
entity.entityData.get(PokemonEntity.HIDE_LABEL),
entity.exposedBall.name,
entity.entityData.get(PokemonEntity.SPAWN_DIRECTION),
entity.entityData.get(PokemonEntity.FRIENDSHIP),
entity.entityData.get(PokemonEntity.FREEZE_FRAME),
entity.passengers.map { it.id }.toIntArray(),
entity.tickCount,
entity.entityData.get(PokemonEntity.RIDE_BOOSTS),
entity.entityData.get(PokemonEntity.RIDE_STAMINA),
vanillaSpawnPacket
)
override fun encodeEntityData(buffer: RegistryFriendlyByteBuf) {
@@ -116,6 +126,7 @@ class SpawnPokemonPacket(
{ _, stat -> buffer.writeEnumConstant(stat) },
{ _, value -> buffer.writeFloat(value) }
)
buffer.writeFloat(rideStamina)
}
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
@@ -123,13 +134,16 @@ class SpawnPokemonPacket(
entity.pokemon.apply {
uuid = this@SpawnPokemonPacket.pokemonUUID
scaleModifier = this@SpawnPokemonPacket.scaleModifier
species = this@SpawnPokemonPacket.speciesId.let { PokemonSpecies.getByIdentifier(it) ?: PokemonSpecies.random() }
species =
this@SpawnPokemonPacket.speciesId.let { PokemonSpecies.getByIdentifier(it) ?: PokemonSpecies.random() }
gender = this@SpawnPokemonPacket.gender
shiny = this@SpawnPokemonPacket.shiny
form = this@SpawnPokemonPacket.formName.let { formName -> species.forms.find { it.formOnlyShowdownId() == formName }} ?: species.standardForm
form =
this@SpawnPokemonPacket.formName.let { formName -> species.forms.find { it.formOnlyShowdownId() == formName } }
?: species.standardForm
forcedAspects = this@SpawnPokemonPacket.aspects
nickname = this@SpawnPokemonPacket.nickname
this@SpawnPokemonPacket.mark?.let {activeMark = Marks.getByIdentifier(it) }
this@SpawnPokemonPacket.mark?.let { activeMark = Marks.getByIdentifier(it) }
PokeBalls.getPokeBall(this@SpawnPokemonPacket.caughtBall)?.let { caughtBall = it }
}
entity.phasingTargetId = this.phasingTargetId
@@ -146,6 +160,7 @@ class SpawnPokemonPacket(
entity.entityData.set(PokemonEntity.FRIENDSHIP, friendship)
entity.entityData.set(PokemonEntity.FREEZE_FRAME, freezeFrame)
entity.entityData.set(PokemonEntity.RIDE_BOOSTS, rideBoosts)
entity.entityData.set(PokemonEntity.RIDE_STAMINA, rideStamina)
entity.ejectPassengers()
passengers.forEach {
@@ -189,9 +204,38 @@ class SpawnPokemonPacket(
{ buffer.readEnumConstant(RidingStat::class.java) },
{ buffer.readFloat() }
)
val rideStamina = buffer.readFloat()
val vanillaPacket = decodeVanillaPacket(buffer)
return SpawnPokemonPacket(ownerId, pokemonUUID, scaleModifier, speciesId, gender, shiny, formName, aspects, battleId, phasingTargetId, beamModeEmitter, platform, nickname, mark, labelLevel, poseType, unbattlable, hideLabel, caughtBall, spawnAngle, friendship, freezeFrame, passengers, tickSpawned, rideBoosts, vanillaPacket)
return SpawnPokemonPacket(
ownerId,
pokemonUUID,
scaleModifier,
speciesId,
gender,
shiny,
formName,
aspects,
battleId,
phasingTargetId,
beamModeEmitter,
platform,
nickname,
mark,
labelLevel,
poseType,
unbattlable,
hideLabel,
caughtBall,
spawnAngle,
friendship,
freezeFrame,
passengers,
tickSpawned,
rideBoosts,
rideStamina,
vanillaPacket
)
}
}
@@ -358,16 +358,29 @@ open class Pokemon : ShowdownIdentifiable {
var currentFullness = 0
set(value) {
if (value < 0) {
field = 0
return
}
FULLNESS_UPDATED.post(FullnessUpdatedEvent(this, value)) {
val clamped = value.coerceIn(0, getMaxFullness())
if (field == clamped) return
FULLNESS_UPDATED.post(FullnessUpdatedEvent(this, clamped)) {
field = it.newFullness
onChange(FullnessUpdatePacket({ this }, it.newFullness))
}
}
/**
* Just a persistence version of the ride stamina used to hold onto
* it between one ride and another. Only applied at the moment of
* mounting the Pokémon.
*/
var rideStamina = 1F
set(value) {
val newValue = value.coerceIn(0F, 1F)
if (newValue != field) {
field = newValue
onChange(RideStaminaUpdatePacket({ this }, newValue))
}
}
var interactionCooldowns: MutableMap<ResourceLocation, Int> = mutableMapOf()
var state: PokemonState = InactivePokemonState()
@@ -1854,19 +1867,40 @@ open class Pokemon : ShowdownIdentifiable {
}
val max = getMaxRideBoost(stat)
rideBoosts[stat] = (getRideBoost(stat) + boostAmount).coerceAtMost(max)
onChange(RideBoostsUpdatePacket({ this }, rideBoosts))
onChange(RideBoostsUpdatePacket({ this }, getRideBoosts()))
return true
}
fun addRideBoosts(boosts: Map<RidingStat, Float>) {
var changed = false
for (boost in boosts) {
val (stat, boostAmount) = boost
if (!canAddRideBoost(stat)) {
continue
}
val max = getMaxRideBoost(stat)
rideBoosts[stat] = (getRideBoost(stat) + boostAmount).coerceAtMost(max)
changed = true
}
if (changed) {
onChange(RideBoostsUpdatePacket({ this }, getRideBoosts()))
}
}
fun setRideBoost(stat: RidingStat, boost: Float) {
rideBoosts[stat] = boost.coerceIn(0F, getMaxRideBoost(stat))
onChange(RideBoostsUpdatePacket({ this }, rideBoosts))
onChange(RideBoostsUpdatePacket({ this }, getRideBoosts()))
}
fun setRideBoosts(boosts: Map<RidingStat, Float>) {
rideBoosts.clear()
rideBoosts.putAll(boosts.mapValues { it.value.coerceIn(0F, getMaxRideBoost(it.key)) })
onChange(RideBoostsUpdatePacket({ this }, rideBoosts))
onChange(RideBoostsUpdatePacket({ this }, getRideBoosts()))
}
fun getExperienceToNextLevel() = getExperienceToLevel(level + 1)
@@ -136,6 +136,7 @@ internal object PropertiesCompletionProvider : DataRegistry {
this.inject(setOf("shiny", "s"), setOf("yes", "no"))
this.inject(setOf("gender"), Gender.values().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 })
@@ -74,7 +74,7 @@ fun <T> ByteBuf.writeCollection(collection: Collection<T> , writer: (ByteBuf, T)
}
fun <T> ByteBuf.writeNullable(obj: T?, writer: (ByteBuf, T) -> Unit) {
this.writeBoolean(obj == null)
this.writeBoolean(obj != null)
obj?.let {
writer(this, it)
}
@@ -101,6 +101,11 @@ fun ByteBuf.writeExpression(expression: Expression): ByteBuf {
return this.writeString(expression.getString())
}
fun ByteBuf.writeNullableExpression(expression: Expression?): ByteBuf {
this.writeNullable(expression) { buf, expr -> buf.writeExpression(expr) }
return this
}
fun ByteBuf.writeRidingStats(stats: Map<RidingStat, IntRange>) {
return this.writeMap(
stats,
@@ -120,6 +125,10 @@ fun ByteBuf.readExpression(): Expression {
return this.readString().asExpression()
}
fun ByteBuf.readNullableExpression(): Expression? {
return this.readNullable { buf -> buf.readExpression() }
}
fun <T> ByteBuf.readNullable(reader: (ByteBuf) -> T): T? {
val isPresent = this.readBoolean()
if (isPresent) {
@@ -60,6 +60,7 @@ object DataKeys {
const val POKEMON_POTENTIAL_MARKS = "Potential Marks"
const val POKEMON_MARKINGS = "Markings"
const val POKEMON_RIDE_BOOSTS = "RideBoosts"
const val POKEMON_RIDE_STAMINA = "RideStamina"
const val POKEMON_STATE = "State"
const val POKEMON_STATE_TYPE = "StateType"
@@ -27,6 +27,7 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.RegistryAccess
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.packs.resources.Resource
import net.minecraft.world.InteractionHand
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.item.ItemStack
@@ -35,7 +36,7 @@ import net.minecraft.world.level.pathfinder.Path
import net.minecraft.world.phys.shapes.VoxelShape
import org.joml.Vector4f
fun cobblemonResource(path: String) = ResourceLocation.fromNamespaceAndPath(Cobblemon.MODID, path)
fun cobblemonResource(path: String): ResourceLocation = ResourceLocation.fromNamespaceAndPath(Cobblemon.MODID, path)
fun cobblemonModel(path: String, variant: String) =
ModelResourceLocation(cobblemonResource(path), variant)
@@ -14,7 +14,7 @@ import net.minecraft.advancements.critereon.MinMaxBounds
import java.lang.reflect.Type
/**
* A type adapter for [NumberRange.DoubleRange].
* A type adapter for [MinMaxBounds.Doubles].
*
* @author Licious
* @since November 28th, 2022
@@ -41,6 +41,7 @@ internal data class PokemonP3(
val potentialMarks: Set<ResourceLocation>,
val markings: List<Int>,
val rideBoosts: Map<String, Float>,
val rideStamina: Float,
val currentFullness: Int,
val interactionCooldowns: Map<ResourceLocation, Int>
) : Partial<Pokemon> {
@@ -77,6 +78,7 @@ internal data class PokemonP3(
other.potentialMarks += this.potentialMarks.map { Marks.getByIdentifier(it) }.filterNotNull().toMutableSet()
other.markings = this.markings
this.rideBoosts.let { other.setRideBoosts(it.mapKeys { RidingStat.valueOf(it.key) }) }
other.rideStamina = this.rideStamina
other.currentFullness = this.currentFullness
other.interactionCooldowns = this.interactionCooldowns.toMutableMap()
return other
@@ -97,9 +99,10 @@ internal data class PokemonP3(
Codec.list(ResourceLocation.CODEC).optionalFieldOf(DataKeys.POKEMON_POTENTIAL_MARKS, emptyList()).forGetter { it.potentialMarks.toMutableList() },
Codec.list(Codec.INT).optionalFieldOf(DataKeys.POKEMON_MARKINGS, listOf(0, 0, 0, 0, 0, 0)).forGetter(PokemonP3::markings),
Codec.unboundedMap(Codec.STRING, Codec.FLOAT).optionalFieldOf(DataKeys.POKEMON_RIDE_BOOSTS, emptyMap<String, Float>()).forGetter(PokemonP3::rideBoosts),
Codec.FLOAT.optionalFieldOf(DataKeys.POKEMON_RIDE_STAMINA, 1F).forGetter(PokemonP3::rideStamina),
Codec.intRange(0, 100).optionalFieldOf(DataKeys.POKEMON_FULLNESS, 0).forGetter(PokemonP3::currentFullness),
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).optionalFieldOf(DataKeys.POKEMON_INTERACTION_COOLDOWN, emptyMap<ResourceLocation, Int>()).forGetter(PokemonP3::interactionCooldowns)
).apply(instance) { originalTrainerType, originalTrainer, forcedAspects, features, heldItemVisible, canDropHeldItem, cosmeticItem, activeMark, marks, potentialMarks, markings, rideBoosts, currentFullness, interactionCooldown -> PokemonP3(originalTrainerType, originalTrainer, forcedAspects.toSet(), features, heldItemVisible, canDropHeldItem, cosmeticItem.orElse(ItemStack.EMPTY), activeMark, marks.toMutableSet(), potentialMarks.toMutableSet(), markings, rideBoosts, currentFullness, interactionCooldown) }
).apply(instance) { originalTrainerType, originalTrainer, forcedAspects, features, heldItemVisible, canDropHeldItem, cosmeticItem, activeMark, marks, potentialMarks, markings, rideBoosts, rideStamina, currentFullness, interactionCooldown -> PokemonP3(originalTrainerType, originalTrainer, forcedAspects.toSet(), features, heldItemVisible, canDropHeldItem, cosmeticItem.orElse(ItemStack.EMPTY), activeMark, marks.toMutableSet(), potentialMarks.toMutableSet(), markings, rideBoosts, rideStamina, currentFullness, interactionCooldown) }
}
internal fun from(pokemon: Pokemon): PokemonP3 = PokemonP3(
@@ -119,6 +122,7 @@ internal data class PokemonP3(
pokemon.potentialMarks.map { it.identifier }.toSet(),
pokemon.markings,
pokemon.getRideBoosts().mapKeys { it.key.name },
pokemon.rideStamina,
pokemon.currentFullness,
pokemon.interactionCooldowns
)
@@ -21,7 +21,7 @@
"per_update_expression": "variable.radius = 0.6;"
},
"minecraft:emitter_rate_steady": {
"spawn_rate": 30,
"spawn_rate": 60,
"max_particles": 10000
},
"minecraft:emitter_lifetime_expression": {
@@ -29,14 +29,14 @@
},
"minecraft:emitter_shape_sphere": {
"offset": [0, 0, -1],
"radius": "1.25+(v.particle_random_4*1.25)",
"radius": "0.85+(v.particle_random_4*1.25)",
"surface_only": true,
"direction": ["math.random(-0.1,0.1)*3", "math.random(-0.1,0.1)*1.25", "-0.5-math.random(-0.1,0.1)*2"]
"direction": ["math.random(-0.1,0.1)*1", "math.random(-0.1,0.1)*1", "-math.random(-0.1,0.1)*1"]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 1
"max_lifetime": 1.25
},
"minecraft:particle_initial_speed": 1,
"minecraft:particle_initial_speed": 0.3,
"minecraft:particle_motion_dynamic": {
"linear_drag_coefficient": "0.25+v.particle_random_4"
},
@@ -50,8 +50,9 @@
"base_UV": [0, 0],
"size_UV": [9, 9],
"step_UV": [9, 0],
"frames_per_second": 20,
"max_frame": 11
"frames_per_second": 12,
"max_frame": 11,
"loop": true
}
}
},
@@ -163,7 +163,7 @@
},
"animation.exeggutor.ground_walk": {
"loop": true,
"animation_length": 4.79167,
"animation_length": 4.7917,
"bones": {
"leg_left": {
"rotation": {
@@ -724,126 +724,36 @@
}
}
},
"animation.exeggutor.cry": {
"animation_length": 1.5,
"bones": {
"mouth": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -2, 0],
"1.25": [0, -2, 0],
"1.5": [0, 0, 0]
}
},
"mouth2": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -5, 0],
"1.25": [0, -5, 0],
"1.5": [0, 0, 0]
}
},
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -3, 0],
"1.25": [0, -3, 0],
"1.5": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-15, 0, 0],
"1.25": [-15, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed": {
"position": {
"0.0": [0, 0, -0.1],
"0.25": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0.1],
"0.25": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
}
},
"head2": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-15, 0, 0],
"1.25": [-15, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed2": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.2]},
"1.25": {"pre": [0, 0, 0.2], "post": [0, 0, 0]}
}
},
"mouth_open2": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.25": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"head3": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-15, 0, 0],
"1.25": [-15, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed3": {
"position": {
"0.0": [0, 0, -0.1],
"0.25": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
}
},
"mouth_open3": {
"position": {
"0.0": [0, 0, 0.1],
"0.25": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
}
}
}
},
"animation.exeggutor.battle_idle": {
"loop": true,
"animation_length": 1.58333,
"animation_length": 1.5833,
"bones": {
"leg_left": {
"rotation": {
"0.0": ["-15+math.clamp(-math.sin(q.anim_time*90*2.5+225)*65,-90,0)", -35, 0],
"0.0": [-15, -35, 0],
"0.5833": [-15, -35, 0],
"0.625": ["-15+math.clamp(-math.sin(q.anim_time*90*2.5+225)*65,-90,0)", -35, 0],
"1.125": ["-15+math.clamp(-math.sin(q.anim_time*90*2.5+225)*65,-90,0)", -35, 0],
"0.7917": [-65, -35, 0],
"0.9583": {
"pre": [-75, -35, 0],
"post": [-75, -35, 0],
"lerp_mode": "catmullrom"
},
"1.125": {
"post": [-65, -35, 0],
"lerp_mode": "catmullrom"
},
"1.2917": [-15, -35, 0],
"1.5833": [-15, -35, 0]
},
"position": {
"0.0": [
"math.clamp(math.sin(q.anim_time*90*2.5+225)*0.5,0,90)",
"math.clamp(math.sin(q.anim_time*90*2.5+225)*3.5,0,90)",
"math.clamp(-math.sin(q.anim_time*90*2.5+225)*2,-90,0)"
],
"0.0": [0, 0, 0],
"0.5833": [0, 0, 0],
"0.625": [
"math.clamp(math.sin(q.anim_time*90*2.5+225)*0.5,0,90)",
"math.clamp(math.sin(q.anim_time*90*2.5+225)*3.5,0,90)",
"math.clamp(-math.sin(q.anim_time*90*2.5+225)*2,-90,0)"
],
"0.625": [0.06, 0.42, -0.24],
"0.7083": [0.18, 1.26, -0.72],
"0.7917": [0.15, 1.08, -0.62],
"0.9167": [0.11, 0.81, -0.47],
"1.0417": [0.07, 0.54, -0.31],
"1.1667": [0.04, 0.27, -0.16],
"1.2917": [0, 0, 0],
"1.5833": [0, 0, 0]
}
@@ -852,7 +762,7 @@
"rotation": {
"0.0": [20, 0, 0],
"0.5833": [20, 0, 0],
"0.875": [5, 0, 0],
"0.875": [40, 0, 0],
"1.125": [20, 0, 0]
}
},
@@ -860,53 +770,55 @@
"rotation": {
"0.0": [-5, 0, 0],
"0.5833": [-5, 0, 0],
"0.7083": [30, 0, 0],
"0.9167": [10, 0, 0],
"1.125": [-5, 0, 0],
"1.25": [-5, 0, 0]
"0.7083": [17.5, 0, 0],
"0.9167": [-5, 0, 0]
}
},
"leg_right": {
"rotation": {
"0.0": ["-15+math.clamp(math.sin(q.anim_time*90*2.5+225)*65,-90,0)", 35, 0],
"0.3333": ["-15+math.clamp(math.sin(q.anim_time*90*2.5+225)*65,-90,0)", 35, 0],
"0.0": [-65, 35, 0],
"0.1667": {
"pre": [-75, 35, 0],
"post": [-75, 35, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [-65, 35, 0],
"lerp_mode": "catmullrom"
},
"0.5": [-15, 35, 0],
"1.3333": [-15, 35, 0],
"1.375": ["-15+math.clamp(math.sin(q.anim_time*90*2.5+225)*65,-90,0)", 35, 0]
"1.375": [-15, 35, 0],
"1.5833": [-65, 35, 0]
},
"position": {
"0.0": [
"math.clamp(math.sin(q.anim_time*90*2.5+225)*0.5,-90,0)",
"math.clamp(-math.sin(q.anim_time*90*2.5+225)*3.5,0,90)",
"math.clamp(math.sin(q.anim_time*90*2.5+225)*2,-90,0)"
],
"0.0": [-0.37, 2.61, -1.49],
"0.0417": [-0.37, 2.61, -1.49],
"0.125": [-0.3, 2.13, -1.22],
"0.25": [-0.2, 1.42, -0.81],
"0.375": [-0.1, 0.71, -0.4],
"0.5": [0, 0, 0],
"1.3333": [0, 0, 0],
"1.375": [
"math.clamp(math.sin(q.anim_time*90*2.5+225)*0.5,-90,0)",
"math.clamp(-math.sin(q.anim_time*90*2.5+225)*3.5,0,90)",
"math.clamp(math.sin(q.anim_time*90*2.5+225)*2,-90,0)"
]
"1.375": [0, 0, 0],
"1.5833": [-0.37, 2.61, -1.49]
}
},
"leg_right2": {
"rotation": {
"0.0": [7, 0, 0],
"0.125": [5, 0, 0],
"0.0": [35, 0, 0],
"0.125": [40, 0, 0],
"0.375": [20, 0, 0],
"1.375": [20, 0, 0],
"1.5833": [7, 0, 0]
"1.5833": [35, 0, 0]
}
},
"foot_right": {
"rotation": {
"0.0": [22, 0, 0],
"0.125": [10, 0, 0],
"0.3333": [-5, 0, 0],
"0.4583": [-5, 0, 0],
"0.0": [4, 0, 0],
"0.0833": [-5, 0, 0],
"1.375": [-5, 0, 0],
"1.5": [30, 0, 0],
"1.5833": [22, 0, 0]
"1.5": [17.5, 0, 0],
"1.5833": [8.5, 0, 0]
}
},
"body": {
@@ -1063,6 +975,106 @@
}
}
},
"animation.exeggutor.cry": {
"animation_length": 1.5,
"bones": {
"mouth": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -2, 0],
"1.25": [0, -2, 0],
"1.5": [0, 0, 0]
}
},
"mouth2": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -5, 0],
"1.25": [0, -5, 0],
"1.5": [0, 0, 0]
}
},
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -3, 0],
"1.25": [0, -3, 0],
"1.5": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-5, 0, 0],
"1.25": [-2.5, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed": {
"position": {
"0.0": [-1, 0, -0.1],
"0.25": {"pre": [-1, 0, -0.1], "post": [-1, 0, 0]},
"1.25": {"pre": [-1, 0, 0], "post": [-1, 0, -0.1]}
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0.1],
"0.25": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
}
},
"head2": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-5, 0, 0],
"1.25": [-2.5, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed2": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.2]},
"1.25": {"pre": [0, 0, 0.2], "post": [0, 0, 0]}
}
},
"mouth_open2": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.25": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"head3": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-5, 0, 0],
"1.25": [-2.5, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed3": {
"position": {
"0.0": [-1, 0, -0.1],
"0.25": {"pre": [-1, 0, -0.1], "post": [-1, 0, 0]},
"1.25": {"pre": [-1, 0, 0], "post": [-1, 0, -0.1]}
}
},
"mouth_open3": {
"position": {
"0.0": [0, 0, 0.1],
"0.25": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
}
}
},
"sound_effects": {
"0.25": {
"effect": "pokemon.exeggutor.cry"
}
}
},
"animation.exeggutor.sleep": {
"loop": true,
"animation_length": 8,
@@ -1294,7 +1306,7 @@
}
},
"animation.exeggutor.blink3": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eyelid_right3": {
"position": {
@@ -5,47 +5,78 @@
"loop": true,
"bones": {
"body": {
"rotation": ["5+(math.sin(q.anim_time*90*2*1+180)*6)*0.6", 0, "0+(math.sin(q.anim_time*90*2*1+180)*1)*0.6"],
"position": [0, "2+(math.cos(q.anim_time*90*2*1+180)*0.8)*0.6", 0]
"rotation": ["-5+math.cos(query.anim_time*90*1)*2", 0, "0+math.cos(query.anim_time*90*1/2)*2"],
"position": ["0+math.sin(query.anim_time*90*1/2)*0.75", "3+math.sin(query.anim_time*90*1)*0.5", 0]
},
"torso_top": {
"rotation": ["0-(math.sin(q.anim_time*90*2*1+180)*1.5)*0.6", 0, 0]
"rotation": ["2.5-math.cos(query.anim_time*90*1-30)*2", 0, "0+math.cos(query.anim_time*90*1/2-60)*2"]
},
"collar_back": {
"rotation": ["0-(math.sin(q.anim_time*90*2*1+180)*5)*0.6", 0, 0]
"rotation": ["0+math.cos(query.anim_time*90*1-30)*2", 0, 0]
},
"collar_front": {
"rotation": ["0+(math.sin(q.anim_time*90*2*1+180)*5)*0.6", 0, 0]
"rotation": ["27.5-math.cos(query.anim_time*90*1-60)*1", 0, 0]
},
"head": {
"rotation": ["5-(math.sin(q.anim_time*90*2*1+180)*3)*0.6", 0, 0]
"eyes_bright": {
"position": [0, 0, -0.1]
},
"arm_right": {
"rotation": [0, "(math.sin(q.anim_time*90*2*1+180)*2)*1", "-60-(math.sin(q.anim_time*90*2*1+180)*2)*0.6"]
"rotation": [
"26.4641+math.cos(query.anim_time*90*1/2-120)*7",
"19.3475-math.cos(query.anim_time*90*1/2-60)*6",
"-42.5248-math.cos(query.anim_time*90*1-90)*2"
]
},
"arm_right2": {
"rotation": [0, "0+(math.cos(q.anim_time*90*2*1+180)*1)*0.6", 0]
"rotation": [
"48.1034+math.cos(query.anim_time*90*1-90)*6",
"-28.22+math.cos(query.anim_time*90*1/2-90)*8",
"-9.9783-math.cos(query.anim_time*90*1-120)*6"
]
},
"hand_right": {
"rotation": [0, 0, -10]
"rotation": [12.42995, "-10.0859-math.cos(query.anim_time*90*1-120)*5", "-31.3315+math.cos(query.anim_time*90*1-150)*6"]
},
"arm_left": {
"rotation": [0, "-(math.sin(q.anim_time*90*2*1+180)*2)*1", "60+(math.sin(q.anim_time*90*2*1+180)*2)*0.6"]
"rotation": [
"26.4641+math.cos(query.anim_time*90*1/2-120)*7",
"-19.3475+math.cos(query.anim_time*90*1/2-60)*6",
"42.5248+math.cos(query.anim_time*90*1-90)*2"
]
},
"arm_left2": {
"rotation": [0, "0-(math.sin(q.anim_time*90*2*1+180)*5)*0.6", 0]
"rotation": [
"48.1034+math.cos(query.anim_time*90*1-90)*6",
"28.22-math.cos(query.anim_time*90*1/2-90)*8",
"9.9783+math.cos(query.anim_time*90*1-120)*6"
]
},
"hand_left": {
"rotation": [0, 0, 10]
"rotation": [12.42995, "10.0859+math.cos(query.anim_time*90*1-120)*5", "31.3315-math.cos(query.anim_time*90*1-150)*6"]
},
"torso_bottom": {
"rotation": ["-7.5+math.cos(query.anim_time*90*1-60)*2", 0, "0-math.cos(query.anim_time*90*1/2-120)*2"]
},
"bottom_coat": {
"rotation": ["0-(math.cos(q.anim_time*90*2*1+180)*3)*0.6", 0, 0]
"rotation": ["-3+math.cos(query.anim_time*90*1-90)*2", 0, "0-math.cos(query.anim_time*90*1/2-90)*3"]
},
"leg_right": {
"rotation": ["0+(math.sin(q.anim_time*90*2*1+180)*3)*0.6", 0, "0-(math.sin(q.anim_time*90*2*1+180)*3)*0.6"]
"rotation": ["2.5062+math.cos(query.anim_time*90*1-120)*6", 10.02087, "2.4142-math.cos(query.anim_time*90*1/2-90)*8"]
},
"leg_right2": {
"rotation": ["22.5+math.cos(query.anim_time*90*1-170)*10", 0, "NaN-math.cos(query.anim_time*90*1/2-150)*6"]
},
"leg_left": {
"rotation": ["0+(math.sin(q.anim_time*90*2*1+180)*3)*0.6", 0, "0+(math.sin(q.anim_time*90*2*1+180)*3)*0.6"]
"rotation": ["2.5062+math.cos(query.anim_time*90*1-120)*6", -10.02087, "-2.4142-math.cos(query.anim_time*90*1/2-90)*8"]
},
"leg_left2": {
"rotation": ["22.5+math.cos(query.anim_time*90*1-170)*10", 0, "-math.cos(query.anim_time*90*1/2-150)*6"]
},
"eyes_dim": {
"position": [0, 0, 0.1]
},
"head": {
"rotation": ["15+math.cos(query.anim_time*90*1)*1", 0, "0-math.cos(query.anim_time*90*1/2-120)*3"]
}
}
},
@@ -53,47 +84,157 @@
"loop": true,
"bones": {
"body": {
"rotation": ["17.5-(math.cos(q.anim_time*90*2*1+180)*10)*0.6", 0, "0-(math.sin(q.anim_time*90*2*1+180)*1)*0.6"],
"position": [0, "2+(math.cos(q.anim_time*90*2*1+180)*1.5)*0.6", "0+(math.sin(q.anim_time*90*2*1+180)*1.8)*0.6"]
"rotation": ["25+math.cos(query.anim_time*90*3/2)*2", "0+math.cos(query.anim_time*90*3/2/2)*4", "0+math.cos(query.anim_time*90*3/2/2-60)*2"],
"position": ["0-math.cos(query.anim_time*90*3/2/2-30)*1", "3+math.sin(query.anim_time*90*3/2)*0.7", "0-math.sin(query.anim_time*90*3/2-60)*1"]
},
"torso_top": {
"rotation": ["0+(math.cos(q.anim_time*90*2*1+180)*3)*0.6", 0, 0]
"rotation": ["10-math.cos(query.anim_time*90*3/2-30)*2", "0+math.cos(query.anim_time*90*3/2/2)*4", 0]
},
"collar_back": {
"rotation": ["0-(math.cos(q.anim_time*90*2*1+180)*6)*0.6", 0, 0]
"rotation": ["-15+math.cos(query.anim_time*90*3/2-30)*2", "0+math.cos(query.anim_time*90*3/2/2-90)*2", 0]
},
"collar_front": {
"rotation": ["0+(math.cos(q.anim_time*90*2*1+180)*6)*0.6", 0, 0]
"rotation": ["27.5-math.cos(query.anim_time*90*3/2-60)*1", 0, 0]
},
"head": {
"rotation": ["0+(math.cos(q.anim_time*90*2*1+180)*6)*0.6", 0, 0]
"eyes_bright": {
"position": [0, 0, -0.1]
},
"arm_right": {
"rotation": [0, "20-(math.sin(q.anim_time*90*2*1+180)*3)*0.6", "-55-(math.sin(q.anim_time*90*2*1+180)*6)*0.6"]
"rotation": [
"20.433+math.cos(query.anim_time*90*3/2/2-120)*7",
"31.8177-math.cos(query.anim_time*90*3/2-60)*6",
"-45.313-math.cos(query.anim_time*90*3/2-90)*2"
]
},
"arm_right2": {
"rotation": ["-(math.cos(q.anim_time*90*2*1+180)*6)*0.6", 0, "0+(math.cos(q.anim_time*90*2*1+180)*1)*0.6"]
"rotation": [
"39.442+math.cos(query.anim_time*90*3/2-90)*6",
"-27.7035+math.cos(query.anim_time*90*3/2-90)*8",
"-8.2892-math.cos(query.anim_time*90*3/2-120)*6"
]
},
"hand_right": {
"rotation": [0, 0, -10]
"rotation": [19.42631, "0.9236-math.cos(query.anim_time*90*3/2-120)*5", "-39.9562+math.cos(query.anim_time*90*3/2-150)*6"]
},
"arm_left": {
"rotation": [0, "-20+(math.sin(q.anim_time*90*2*1+180)*3)*0.6", "55+(math.sin(q.anim_time*90*2*1+180)*6)*0.6"]
"rotation": [
"20.433+math.cos(query.anim_time*90*3/2/2-120)*7",
"-31.8177+math.cos(query.anim_time*90*3/2-60)*6",
"45.313+math.cos(query.anim_time*90*3/2-90)*2"
]
},
"arm_left2": {
"rotation": ["(math.cos(q.anim_time*90*2*1+180)*6)*0.6", 0, "0-(math.cos(q.anim_time*90*2*1+180)*1)*0.6"]
"rotation": [
"39.442+math.cos(query.anim_time*90*3/2-90)*6",
"27.7035-math.cos(query.anim_time*90*3/2-90)*8",
"8.2892+math.cos(query.anim_time*90*3/2-120)*6"
]
},
"hand_left": {
"rotation": [0, 0, 10]
"rotation": [19.42631, "-0.9236+math.cos(query.anim_time*90*3/2-120)*5", "39.9562-math.cos(query.anim_time*90*3/2-150)*6"]
},
"torso_bottom": {
"rotation": ["2.5+math.cos(query.anim_time*90*3/2-60)*2", 0, "0+math.cos(query.anim_time*90*3/2/2-60)*4"]
},
"bottom_coat": {
"rotation": ["-2.5-(math.cos(q.anim_time*90*2*1+180)*6)*0.6", 0, 0]
"rotation": ["-8+math.cos(query.anim_time*90*3/2-90)*2", "0+math.cos(query.anim_time*90*3/2/2-120)*2", "0+math.cos(query.anim_time*90*3/2/2-120)*2"]
},
"leg_right": {
"rotation": ["0-(math.cos(q.anim_time*90*2*1+180)*5)*2", 0, "0-(math.cos(q.anim_time*90*2*1+180)*1)*2"]
"rotation": ["4.5574+math.cos(query.anim_time*90*3/2-120)*6", 10.64348, 7.53105]
},
"leg_right2": {
"rotation": ["22.5+math.cos(query.anim_time*90*3/2-170)*10", 0, 0]
},
"leg_left": {
"rotation": ["0-(math.cos(q.anim_time*90*2*1+180)*5)*2", 0, "0+(math.cos(q.anim_time*90*2*1+180)*1)*2"]
"rotation": ["4.5574+math.cos(query.anim_time*90*3/2-120)*6", -10.64348, -7.53105]
},
"leg_left2": {
"rotation": ["22.5+math.cos(query.anim_time*90*3/2-170)*10", 0, 0]
},
"eyes_dim": {
"position": [0, 0, 0.1]
},
"head": {
"rotation": ["-12.5+math.cos(query.anim_time*90*3/2)*3", "0-math.cos(query.anim_time*90*3/2/2)*4", 0]
}
}
},
"animation.beheeyem.battle_idle": {
"loop": true,
"bones": {
"body": {
"rotation": ["-5+math.cos(query.anim_time*90*1)*2", 0, "0+math.cos(query.anim_time*90*1/2)*1"],
"position": ["0+math.sin(query.anim_time*90*1/2)*0.5", "3+math.sin(query.anim_time*90*1)*0.5", 0]
},
"torso_top": {
"rotation": ["2.5-math.cos(query.anim_time*90*1-30)*2", 0, "0+math.cos(query.anim_time*90*1/2-60)*2"]
},
"collar_back": {
"rotation": ["7.5+math.cos(query.anim_time*90*1-30)*2", 0, 0]
},
"collar_front": {
"rotation": ["27.5-math.cos(query.anim_time*90*1-60)*1", 0, 0]
},
"eyes_bright": {
"position": [0, 0, -0.1]
},
"arm_right": {
"rotation": [
"19.1787+math.cos(query.anim_time*90*1/2-120)*4",
"22.2175-math.cos(query.anim_time*90*1-60)*3",
"-48.3831-math.cos(query.anim_time*90*1-90)*2"
]
},
"arm_right2": {
"rotation": ["38.8131+math.cos(query.anim_time*90*1-90)*6", "-35.024+math.cos(query.anim_time*90*1-90)*4", "3.02+math.cos(query.anim_time*90*1-120)*2"]
},
"hand_right": {
"rotation": [17.41964, "-20.6269-math.cos(query.anim_time*90*1-120)*3", "-23.4374+math.cos(query.anim_time*90*1-150)*8"]
},
"arm_left": {
"rotation": [
"19.1787+math.cos(query.anim_time*90*1/2-120)*4",
"-22.2175+math.cos(query.anim_time*90*1-60)*3",
"48.3831+math.cos(query.anim_time*90*1-90)*2"
]
},
"arm_left2": {
"rotation": ["38.8131+math.cos(query.anim_time*90*1-90)*6", "35.024-math.cos(query.anim_time*90*1-90)*4", "-3.02-math.cos(query.anim_time*90*1-120)*2"]
},
"hand_left": {
"rotation": [17.41964, "20.6269+math.cos(query.anim_time*90*1-120)*3", "23.4374-math.cos(query.anim_time*90*1-150)*8"]
},
"torso_bottom": {
"rotation": ["-7.5+math.cos(query.anim_time*90*1-60)*2", 0, "0-math.cos(query.anim_time*90*1/2-120)*1"]
},
"bottom_coat": {
"rotation": ["-10.5+math.cos(query.anim_time*90*1-90)*2", 0, "-math.cos(query.anim_time*90*1/2-90)*2"]
},
"leg_right": {
"rotation": ["2.0651+math.cos(query.anim_time*90*1-120)*6", 9.9897, "-0.1242-math.cos(query.anim_time*90*1/2-90)*4"]
},
"leg_right2": {
"rotation": ["22.5+math.cos(query.anim_time*90*1-170)*10", 0, "NaN-math.cos(query.anim_time*90*1/2-150)*3"]
},
"leg_left": {
"rotation": ["2.9483+math.cos(query.anim_time*90*1-120)*6", -10.03277, "-4.953-math.cos(query.anim_time*90*1/2-90)*4"]
},
"leg_left2": {
"rotation": ["22.5+math.cos(query.anim_time*90*1-170)*10", 0, "-math.cos(query.anim_time*90*1/2-150)*3"]
},
"pupil_left": {
"position": [0, 0, -0.1],
"scale": 0.75
},
"pupil_right": {
"position": [0, 0, -0.1],
"scale": 0.75
},
"eyes_dim": {
"position": [0, 0, 0.1]
},
"head": {
"rotation": ["25+math.cos(query.anim_time*90*1)*1", 0, "0-math.cos(query.anim_time*90*1/2-120)*3"]
}
}
},
@@ -101,50 +242,341 @@
"loop": true,
"bones": {
"body": {
"rotation": ["0+(math.sin(q.anim_time*90*1+180)*1.5)*0.6", 0, "0+(math.sin(q.anim_time*90*1+180)*3)*0.6"],
"position": [0, "1+(math.cos(q.anim_time*90*1+180)*0.8)*0.6", 0]
"rotation": [40, 0, 0],
"position": [0, 3, 0]
},
"torso_top": {
"rotation": ["0+(math.sin(q.anim_time*90*1+180)*5)*0.6", 0, 0]
},
"collar_back": {
"rotation": ["0-(math.cos(q.anim_time*90*1+180)*3)*0.6", 0, 0]
},
"collar_front": {
"rotation": ["0-(math.cos(q.anim_time*90*1+180)*3)*0.6", 0, 0]
},
"head": {
"rotation": ["25+(math.sin(q.anim_time*90*1+180)*3)*0.6", 0, 0]
},
"arm_right": {
"rotation": [0, "0-(math.cos(q.anim_time*90*1+180)*10)*0.3", "-60+(math.sin(q.anim_time*90*1+180)*5)*0.6"]
},
"arm_right2": {
"rotation": [0, "0-(math.cos(q.anim_time*90*1+180)*10)*0.3", 0]
},
"hand_right": {
"rotation": [0, 0, -10]
},
"arm_left": {
"rotation": [0, "0+(math.cos(q.anim_time*90*1+180)*10)*0.3", "60-(math.sin(q.anim_time*90*1+180)*5)*0.6"]
},
"arm_left2": {
"rotation": [0, "0+(math.cos(q.anim_time*90*1+180)*10)*0.3", 0]
},
"hand_left": {
"rotation": [0, 0, 10]
},
"torso_bottom": {
"rotation": ["0+(math.sin(q.anim_time*90*1+180)*5)*0.6", 0, 0]
},
"bottom_coat": {
"rotation": [-2.5, 0, 0]
},
"collar_back": {
"rotation": [10, 0, 0]
},
"collar_front": {
"rotation": [-15, 0, 0]
},
"arm_right": {
"rotation": [30.18785, -13.49583, -55.38615]
},
"arm_right2": {
"rotation": [8.0521, -19.65857, 17.64818]
},
"hand_right": {
"rotation": [12.21635, -29.21703, -28.76232]
},
"arm_left": {
"rotation": [30.18785, 13.49583, 55.38615]
},
"arm_left2": {
"rotation": [8.0521, 19.65857, -17.64818]
},
"hand_left": {
"rotation": [12.21635, 29.21703, 28.76232]
},
"torso_bottom": {
"rotation": [-17.5, 0, 0]
},
"bottom_coat": {
"rotation": [-17.5, 0, 0]
},
"leg_right": {
"rotation": ["0+(math.sin(q.anim_time*90*1+180)*20)*0.6", 0, "0+(math.cos(q.anim_time*90*1+180)*5)*0.6"]
"rotation": [-22.5, 0, 0]
},
"leg_right2": {
"rotation": [10, 0, 0]
},
"leg_left": {
"rotation": ["0-(math.sin(q.anim_time*90*1+180)*20)*0.6", 0, "0-(math.cos(q.anim_time*90*1+180)*5)*0.6"]
"rotation": [-10, 0, 0]
},
"head": {
"rotation": [20, 0, 0]
}
}
},
"animation.beheeyem.alt_sleep": {
"loop": true,
"bones": {
"body": {
"rotation": [-52.5, 0, 0],
"position": [0, 3, 0]
},
"torso_top": {
"rotation": [2.5, 0, 0]
},
"collar_back": {
"rotation": [5, 0, 0]
},
"collar_front": {
"rotation": [27.5, 0, 0]
},
"arm_right": {
"rotation": [-40.58835, 28.2876, -5.84768]
},
"arm_right2": {
"rotation": [-23.10066, 18.44452, 79.80343]
},
"hand_right": {
"rotation": [-103.94239, -26.14027, 28.61413]
},
"arm_left": {
"rotation": [-40.58835, -28.2876, 5.84768]
},
"arm_left2": {
"rotation": [-23.10066, -18.44452, -79.80343]
},
"hand_left": {
"rotation": [-103.94239, 26.14027, -28.61413]
},
"torso_bottom": {
"rotation": [-12.5, 0, 0]
},
"bottom_coat": {
"rotation": [-17.5, 0, 0]
},
"leg_right": {
"rotation": [-19.76968, -1.50179, -17.43745]
},
"leg_right2": {
"rotation": [10, 0, 0]
},
"leg_left": {
"rotation": [17.24721, -1.93597, 14.87739]
}
}
},
"animation.beheeyem.blink": {
"animation_length": 0.1667,
"bones": {
"eyes_bright": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
}
}
},
"animation.beheeyem.pose": {
"loop": true,
"bones": {
"body": {
"rotation": [-2.5, 0, 0],
"position": [0, 3, 0]
},
"torso_top": {
"rotation": [2.5, 0, 0]
},
"collar_back": {
"rotation": [5, 0, 0]
},
"collar_front": {
"rotation": [-7.5, 0, 0]
},
"eyes_bright": {
"position": [0, 0, -0.1]
},
"arm_right": {
"rotation": [0.18641, 11.50404, -55.30513]
},
"arm_right2": {
"rotation": [24.59434, -22.85086, 0.87852]
},
"hand_right": {
"rotation": [19.6995, -3.27667, -28.1772]
},
"arm_left": {
"rotation": [0.18641, -11.50404, 55.30513]
},
"arm_left2": {
"rotation": [24.59434, 22.85086, -0.87852]
},
"hand_left": {
"rotation": [19.6995, 3.27667, 28.1772]
},
"torso_bottom": {
"rotation": [-2.5, 0, 0]
},
"bottom_coat": {
"rotation": [-17.5, 0, 0]
},
"leg_right": {
"rotation": [-5, 0, 0]
},
"leg_right2": {
"rotation": [10, 0, 0]
},
"leg_left": {
"rotation": [7.5, 0, 0]
},
"leg_left2": {
"rotation": [15, 0, 0]
},
"eyes_dim": {
"position": [0, 0, 0.1]
},
"head": {
"rotation": [10, 0, 0]
}
}
},
"animation.beheeyem.lights_quirk1": {
"loop": true,
"animation_length": 1.5,
"bones": {
"right_finger_bright_red2": {
"scale": {
"0.0": [1.05, 1.05, 1.05],
"0.5": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"1.0": [1, 1, 1],
"1.5": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]}
}
},
"right_finger_bright_yellow": {
"scale": {
"0.0": [1, 1, 1],
"0.5": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"1.0": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"1.5": [1, 1, 1]
}
},
"right_finger_bright_green2": {
"scale": {
"0.0": [1, 1, 1],
"0.5": [1, 1, 1],
"1.0": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"1.5": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]}
}
},
"left_finger_bright_red2": {
"scale": {
"0.0": [1.05, 1.05, 1.05],
"0.5": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"1.0": [1, 1, 1],
"1.5": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]}
}
},
"left_finger_bright_yellow": {
"scale": {
"0.0": [1, 1, 1],
"0.5": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"1.0": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"1.5": [1, 1, 1]
}
},
"left_finger_bright_green2": {
"scale": {
"0.0": [1, 1, 1],
"0.5": [1, 1, 1],
"1.0": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"1.5": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]}
}
}
}
},
"animation.beheeyem.lights_quirk2": {
"loop": true,
"animation_length": 1,
"bones": {
"right_finger_bright_red2": {
"scale": {
"0.0": [1.05, 1.05, 1.05],
"0.3333": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"0.6667": [1, 1, 1],
"1.0": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]}
}
},
"right_finger_bright_yellow": {
"scale": {
"0.0": [1, 1, 1],
"0.3333": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"0.6667": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"1.0": [1, 1, 1]
}
},
"right_finger_bright_green2": {
"scale": {
"0.0": [1, 1, 1],
"0.3333": [1, 1, 1],
"0.6667": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"1.0": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]}
}
},
"left_finger_bright_red2": {
"scale": {
"0.0": [1.05, 1.05, 1.05],
"0.3333": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"0.6667": [1, 1, 1],
"1.0": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]}
}
},
"left_finger_bright_yellow": {
"scale": {
"0.0": [1, 1, 1],
"0.3333": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"0.6667": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"1.0": [1, 1, 1]
}
},
"left_finger_bright_green2": {
"scale": {
"0.0": [1, 1, 1],
"0.3333": [1, 1, 1],
"0.6667": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"1.0": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]}
}
}
}
},
"animation.beheeyem.lights_quirk3": {
"loop": true,
"animation_length": 0.5,
"bones": {
"right_finger_bright_red2": {
"scale": {
"0.0": [1.05, 1.05, 1.05],
"0.1667": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"0.3333": [1, 1, 1],
"0.5": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]}
}
},
"right_finger_bright_yellow": {
"scale": {
"0.0": [1, 1, 1],
"0.1667": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"0.3333": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"0.5": [1, 1, 1]
}
},
"right_finger_bright_green2": {
"scale": {
"0.0": [1, 1, 1],
"0.1667": [1, 1, 1],
"0.3333": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"0.5": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]}
}
},
"left_finger_bright_red2": {
"scale": {
"0.0": [1.05, 1.05, 1.05],
"0.1667": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"0.3333": [1, 1, 1],
"0.5": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]}
}
},
"left_finger_bright_yellow": {
"scale": {
"0.0": [1, 1, 1],
"0.1667": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"0.3333": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]},
"0.5": [1, 1, 1]
}
},
"left_finger_bright_green2": {
"scale": {
"0.0": [1, 1, 1],
"0.1667": [1, 1, 1],
"0.3333": {"pre": [1, 1, 1], "post": [1.05, 1.05, 1.05]},
"0.5": {"pre": [1.05, 1.05, 1.05], "post": [1, 1, 1]}
}
}
}
},
@@ -178,15 +610,6 @@
"1.4583": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": ["0+(math.cos(q.anim_time*90*2*1+180)*0.8)*0.6", 0, 0],
"0.125": [11.5, 0, 0],
"0.4167": ["-6-(math.cos(q.anim_time*90*80+180)*2)*2", 0, 0],
"0.9583": ["-6+(math.cos(q.anim_time*90*8+180)*2)*0.6", 0, 0],
"1.4583": [0, 0, 0]
}
},
"arm_right": {
"rotation": {
"0.0": [0, 0, 0],
@@ -222,11 +645,94 @@
"0.9583": [7.3679, 40.2246, -30.8095],
"1.4583": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": ["0+(math.cos(q.anim_time*90*2*1+180)*0.8)*0.6", 0, 0],
"0.125": [11.5, 0, 0],
"0.4167": ["-6-(math.cos(q.anim_time*90*80+180)*2)*2", 0, 0],
"0.9583": ["-6+(math.cos(q.anim_time*90*8+180)*2)*0.6", 0, 0],
"1.4583": [0, 0, 0]
}
}
},
"sound_effects": {
"0.04": {
"effect": "pokemon.beheeyem.cry"
}
},
"animation.beheeyem.new": {
"loop": true,
"bones": {
"beheeyem": {
"position": [0, 0, "33-query.anim_time*90*0.08"]
}
}
},
"animation.beheeyem.pose2": {
"loop": true,
"bones": {
"body": {
"rotation": [-2.5, 0, 0],
"position": [0, 3, 0]
},
"torso_top": {
"rotation": [2.5, 0, 0]
},
"collar_back": {
"rotation": [5, 0, 0]
},
"collar_front": {
"rotation": [-7.5, 0, 0]
},
"eyes_bright": {
"position": [0, 0, -0.1]
},
"arm_right": {
"rotation": [-16.69715, -44.79233, -31.70444]
},
"arm_right2": {
"rotation": [24.59434, -22.85086, 0.87852]
},
"hand_right": {
"rotation": [19.6995, -3.27667, -28.1772]
},
"arm_left": {
"rotation": [0.18641, -11.50404, 55.30513]
},
"arm_left2": {
"rotation": [24.59434, 22.85086, -0.87852]
},
"hand_left": {
"rotation": [19.6995, 3.27667, 28.1772]
},
"torso_bottom": {
"rotation": [-2.5, 0, 0]
},
"bottom_coat": {
"rotation": [-17.5, 0, 0]
},
"leg_right": {
"rotation": [-5, 0, 0]
},
"leg_right2": {
"rotation": [10, 0, 0]
},
"leg_left": {
"rotation": [7.5, 0, 0]
},
"leg_left2": {
"rotation": [15, 0, 0]
},
"pupil_left": {
"position": [-0.25, 0, -0.1],
"scale": 0.75
},
"pupil_right": {
"position": [-0.25, 0, -0.1],
"scale": 0.75
},
"eyes_dim": {
"position": [0, 0, 0.1]
},
"head": {
"rotation": [10, 0, 0]
}
}
}
@@ -26,6 +26,9 @@
},
"eyes": {
"scale": [1, "1-math.sin(q.anim_time*90)*0.03", 1]
},
"wax_trail": {
"position": [0, 0.02, 0]
}
}
},
@@ -43,7 +46,7 @@
"scale": [1, "1-math.sin(q.anim_time*90*4-135)*0.01", 1]
},
"flame": {
"rotation": ["(math.sin(q.anim_time*90)*6)*(math.sin(q.anim_time*90-90))", 0, "-(math.sin(q.anim_time*90-45)*6)*(math.sin(q.anim_time*90-90))"],
"rotation": ["-2.5+(math.sin(q.anim_time*90)*6)*(math.sin(q.anim_time*90-90))", 0, "0-(math.sin(q.anim_time*90-45)*6)*(math.sin(q.anim_time*90-90))"],
"scale": [1, "1+math.sin(q.anim_time*90*4+125)*0.1", 1]
},
"arm_right": {
@@ -61,7 +64,10 @@
"scale": [1, "1+math.sin(q.anim_time*90*4+90)*0.01", 1]
},
"wax_trail2": {
"position": [0, 0, "0.3-math.sin(q.anim_time*90*4+75)*0.33"]
"scale": [1, 1, "1-math.sin(q.anim_time*90*4+75)*0.1"]
},
"wax_trail": {
"position": [0, 0.03, 0]
}
}
},
@@ -100,7 +106,7 @@
"position": ["(math.sin(q.anim_time*90*2)*0.5)", 0, 0]
},
"wax_trail": {
"position": ["(math.sin(q.anim_time*90*2-90)*0.2)", 0, 0],
"position": ["(math.sin(q.anim_time*90*2-90)*0.2)", 0.02, 0],
"scale": ["1+(math.sin(q.anim_time*90*4+45)*0.04)", 1, 1]
},
"lip": {
@@ -141,7 +147,7 @@
"scale": [1, 0.9, 1]
},
"wax_trail": {
"position": [0, 0.5, 0],
"position": [0, 0.52, 0],
"scale": 1.075
},
"eyelid_right": {
@@ -153,62 +159,129 @@
"lip": {
"rotation": [4.98, 0, 0],
"position": [0, 0, -0.008]
},
"eye_left_open": {
"position": [0, 0, 0.1]
},
"eye_closed_left": {
"position": [0, 0, -0.1]
},
"eye_right_open": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.litwick.blink": {
"animation_length": 0.20833,
"animation_length": 0.1667,
"bones": {
"eyelid_right": {
"eye_left_open": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.1667": [-0.1, 0, -0.1],
"0.2083": [0, 0, 0]
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_left": {
"eye_closed_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.1667": [0.1, 0, -0.1],
"0.2083": [0, 0, 0]
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eye_right_open": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
}
},
"eye_closed_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.litwick.pose": {
"animation.litwick.shock": {
"loop": true,
"bones": {
"head": {
"rotation": [-7.56397, -7.43547, 0.98448]
"eye_left_open": {
"position": [0, 0.25, 0],
"scale": [1, 0.5, 1]
},
"hair": {
"rotation": [-2.5, 0, 0]
"eye_right_open": {
"position": [0, 0.25, 0]
},
"flame": {
"rotation": [-19.8423, -2.55868, -12.05239]
},
"arm_right": {
"rotation": [0, 0, -50]
},
"arm_left": {
"rotation": [0, 0, 52.5]
},
"lip": {
"rotation": [-7.5, 0, 0]
},
"mouth_small": {
"position": [0, 0, 0]
},
"mouth_large": {
"position": [0, 0, 0]
"mouth_open": {
"position": [0, 0, -0.1],
"scale": [0.9, 1, 1]
}
}
},
"animation.litwick.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.litwick.cry"
"animation.litwick.angry": {
"loop": true,
"bones": {
"eye_expression_left": {
"position": [-0.5, 0, -0.1]
},
"eye_expression_right": {
"position": [0.5, 0, -0.1]
}
}
},
"animation.litwick.sad": {
"loop": true,
"bones": {
"eye_expression_left": {
"position": [0.5, 0, -0.1]
},
"eye_expression_right": {
"position": [-0.5, 0, -0.1]
}
}
},
"animation.litwick.happy": {
"loop": true,
"bones": {
"eye_left_open": {
"position": [0, 0, 0.1]
},
"eye_happy_left": {
"position": [0, 0, -0.1]
},
"eye_right_open": {
"position": [0, 0, 0.1]
},
"eye_happy_right": {
"position": [0, 0, -0.1]
},
"mouth_open": {
"position": [0, 0, -0.1],
"scale": [0.9, 1, 1]
}
}
},
"animation.litwick.hurt": {
"loop": true,
"bones": {
"eye_left_open": {
"position": [0, 0, 0.1]
},
"eye_closed_left": {
"rotation": [0, 0, -27.5],
"position": [0, 0, -0.1]
},
"eye_right_open": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"rotation": [0, 0, 27.5],
"position": [0, 0, -0.1]
}
}
}
@@ -20,7 +20,7 @@
"rotation": ["-2.5 + math.sin(q.anim_time*90*2-90)", 5, "7.5 + 5*math.sin(q.anim_time*90*2)"]
},
"arm_left2": {
"rotation": [0, 0, "10 + 5*math.sin(q.anim_time*90*2+90)"]
"rotation": [0, 0, "5*math.sin(q.anim_time*90*2+90)"]
},
"arm_left3": {
"rotation": [0, 0, "10 + 5*math.sin(q.anim_time*90*2+180)"]
@@ -38,7 +38,7 @@
"rotation": ["-2.5+math.sin(q.anim_time*90*2-90)", -5, "-7.5 - 5*math.sin(q.anim_time*90*2)"]
},
"arm_right2": {
"rotation": [0, 0, "-10 - 5*math.sin(q.anim_time*90*2+90)"]
"rotation": [0, 0, "- 5*math.sin(q.anim_time*90*2+90)"]
},
"arm_right3": {
"rotation": [0, 0, "-10 - 5*math.sin(q.anim_time*90*2+180)"]
@@ -59,7 +59,13 @@
"scale": 0
},
"body": {
"position": [0, 4, 0]
"position": [0, 1, 0]
},
"arm_left7": {
"rotation": [0, 0, 57.5]
},
"arm_right7": {
"rotation": [0, 0, -57.5]
}
}
},
@@ -82,7 +88,7 @@
"rotation": ["10.2854 + math.sin(q.anim_time*90*2-90)*2", 6.26335, "18.6835 + 5*math.sin(q.anim_time*90*2)"]
},
"arm_left2": {
"rotation": [0, 0, "18 + 5*math.sin(q.anim_time*90*2+90)"]
"rotation": [0, 0, "10.5 + 5*math.sin(q.anim_time*90*2+90)"]
},
"arm_left3": {
"rotation": [0, 0, "20 + 5*math.sin(q.anim_time*90*2+180)"]
@@ -100,7 +106,7 @@
"rotation": ["10.2854 + math.sin(q.anim_time*90*2-90)*2", -6.26335, "-18.6835+ 5*math.sin(q.anim_time*90*2)"]
},
"arm_right2": {
"rotation": [0, 0, "-18+ 5*math.sin(q.anim_time*90*2+90)"]
"rotation": [0, 0, "-10.5+ 5*math.sin(q.anim_time*90*2+90)"]
},
"arm_right3": {
"rotation": [0, 0, "-20+ 5*math.sin(q.anim_time*90*2+180)"]
@@ -125,6 +131,12 @@
},
"head": {
"rotation": [0, 0, 0]
},
"arm_left7": {
"rotation": [0, 0, 57.5]
},
"arm_right7": {
"rotation": [-2.50463, -13.04546, -71.15153]
}
}
},
@@ -187,6 +199,12 @@
},
"body": {
"position": [0, 4, 0]
},
"arm_left7": {
"rotation": [0, 0, 47.5]
},
"arm_right7": {
"rotation": [0, 0, -47.5]
}
}
},
@@ -209,7 +227,7 @@
"rotation": ["10.2854 + math.sin(q.anim_time*90*2-90)*2", 6.26335, "18.6835 + 5*math.sin(q.anim_time*90*2)"]
},
"arm_left2": {
"rotation": [0, 0, "18 + 5*math.sin(q.anim_time*90*2+90)"]
"rotation": [0, 0, "10.5 + 5*math.sin(q.anim_time*90*2+90)"]
},
"arm_left3": {
"rotation": [0, 0, "20 + 5*math.sin(q.anim_time*90*2+180)"]
@@ -227,7 +245,7 @@
"rotation": ["10.2854 + math.sin(q.anim_time*90*2-90)*2", -6.26335, "-18.6835+ 5*math.sin(q.anim_time*90*2)"]
},
"arm_right2": {
"rotation": [0, 0, "-18+ 5*math.sin(q.anim_time*90*2+90)"]
"rotation": [0, 0, "-10.5+ 5*math.sin(q.anim_time*90*2+90)"]
},
"arm_right3": {
"rotation": [0, 0, "-20+ 5*math.sin(q.anim_time*90*2+180)"]
@@ -252,6 +270,12 @@
},
"head": {
"rotation": [0, 0, 0]
},
"arm_left7": {
"rotation": [0, 0, 57.5]
},
"arm_right7": {
"rotation": [0, 0, -57.5]
}
}
},
@@ -297,13 +321,13 @@
"rotation": [0, 0, "22+5*math.sin(q.anim_time*90*2)*0.5"]
},
"arm_right3": {
"rotation": [0, 0, "35+5*math.sin(q.anim_time*90*2)"]
"rotation": [0, 0, "25+5*math.sin(q.anim_time*90*2)"]
},
"arm_right4": {
"rotation": [0, 0, "19.5+5*math.sin(q.anim_time*90*2)*0.5"]
},
"arm_right5": {
"rotation": [0, 0, "30+5*math.sin(q.anim_time*90*2)*0.5"]
"rotation": [0, 0, "15+5*math.sin(q.anim_time*90*2)*0.5"]
},
"arm_right6": {
"rotation": [0, 0, "24+5*math.sin(q.anim_time*90*2)*0.5"]
@@ -316,6 +340,12 @@
},
"body": {
"position": [0, 4, 0]
},
"arm_left7": {
"rotation": [0, 0, 70]
},
"arm_right7": {
"rotation": [0, 0, 12.5]
}
}
},
@@ -379,31 +409,29 @@
"body": {
"position": [0, 4, 0]
},
"eye_left": {
"scale": 0
"arm_left7": {
"rotation": [0, 0, 67.5]
},
"eye_right": {
"scale": 0
"arm_right7": {
"rotation": [0, 0, -67.5]
},
"eye_left_open": {
"position": [0, 4, 0]
},
"eye_closed_left": {
"position": [0, -4, 0]
},
"eye_right_open": {
"position": [0, 4, 0]
},
"eye_closed_right": {
"position": [0, -4, 0]
}
}
},
"animation.lampent.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eye_left": {
"scale": {
"0.0": [0, 0, 0],
"0.125": [0, 0, 0],
"0.1667": [1, 1, 1]
}
},
"eye_right": {
"scale": {
"0.0": [0, 0, 0],
"0.125": [0, 0, 0],
"0.1667": [1, 1, 1]
}
},
"eyelid_left": {
"scale": {
"0.0": [1, 1, 1],
@@ -417,68 +445,116 @@
"0.125": [1, 1, 1],
"0.1667": [1, 1, 1]
}
},
"eye_left_open": {
"position": {
"0.0": [0, 4, 0],
"0.125": {"pre": [0, 4, 0], "post": [0, 4, 0]},
"0.1667": {"pre": [0, 4, 0], "post": [0, 0, 0]}
}
},
"eye_closed_left": {
"position": {
"0.0": [0, -4, 0],
"0.125": {"pre": [0, -4, 0], "post": [0, -4, 0]},
"0.1667": {"pre": [0, -4, 0], "post": [0, 0, 0]}
}
},
"eye_right_open": {
"position": {
"0.0": [0, 4, 0],
"0.125": {"pre": [0, 4, 0], "post": [0, 4, 0]},
"0.1667": {"pre": [0, 4, 0], "post": [0, 0, 0]}
}
},
"eye_closed_right": {
"position": {
"0.0": [0, -4, 0],
"0.125": {"pre": [0, -4, 0], "post": [0, -4, 0]},
"0.1667": {"pre": [0, -4, 0], "post": [0, 0, 0]}
}
}
}
},
"animation.lampent.pose": {
"animation.lampent.shock": {
"loop": true,
"bones": {
"body": {
"rotation": [0, -5, 7.5]
"eye_left_open": {
"position": [0, 0.25, 0],
"scale": [0.7, 0.7, 1]
},
"head": {
"rotation": [14.60945, 2.9986, -5.59467]
"eye_left_open2": {
"scale": 0
},
"arm_left": {
"rotation": [0, 25, -7.5]
"eye_right_open": {
"position": [0, 0.25, 0],
"scale": [0.7, 0.7, 1]
},
"arm_left2": {
"rotation": [0, 0, -22.5]
},
"arm_left3": {
"rotation": [0, 0, -17.5]
},
"arm_left4": {
"rotation": [0, 0, -22.5]
},
"arm_left5": {
"rotation": [0, 0, -30]
},
"arm_left6": {
"rotation": [0, 0, -28.5]
},
"arm_right": {
"rotation": [0, 0, -5]
},
"arm_right2": {
"rotation": [0, 0, -20]
},
"arm_right3": {
"rotation": [0, 0, -25]
},
"arm_right4": {
"rotation": [0, 0, -40]
},
"arm_right5": {
"rotation": [0, 0, -38.5]
},
"arm_right6": {
"rotation": [0, 0, -36.5]
},
"swing": {
"rotation": [-13.63677, 25.79103, 6.17047],
"position": [4.2, 4, 11]
},
"flame": {
"rotation": [0, 22.5, 0]
"eye_right_open2": {
"position": [-0.25, -0.25, 0],
"scale": 0
}
}
},
"animation.lampent.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.lampent.cry"
"animation.lampent.angry": {
"loop": true,
"bones": {
"eye_left_open2": {
"position": [0.25, -0.25, 0],
"scale": [0.5, 0.5, 1]
},
"eye_right_open2": {
"position": [-0.25, -0.25, 0],
"scale": [0.5, 0.5, 1]
}
}
},
"animation.lampent.sad": {
"loop": true,
"bones": {
"eye_left_open2": {
"position": [-0.25, -0.25, 0],
"scale": [0.5, 0.5, 1]
},
"eye_right_open2": {
"position": [0.25, -0.25, 0],
"scale": [0.5, 0.5, 1]
}
}
},
"animation.lampent.happy": {
"loop": true,
"bones": {
"eye_left_open": {
"position": [0, 4, 0]
},
"eye_happy_left": {
"position": [0, -4, 0]
},
"eye_right_open": {
"position": [0, 4, 0]
},
"eye_happy_right": {
"position": [0, -4, 0]
}
}
},
"animation.lampent.hurt": {
"loop": true,
"bones": {
"eye_left_open": {
"position": [0, 4, 0]
},
"eye_closed_left": {
"rotation": [0, 0, -20],
"position": [0, -4, 0]
},
"eye_right_open": {
"position": [0, 4, 0]
},
"eye_closed_right": {
"rotation": [0, 0, 20],
"position": [0, -4, 0]
}
}
}
@@ -31,6 +31,14 @@
"top": [0, 38, 0]
}
},
{
"name": "locator_target",
"parent": "manectric",
"pivot": [0, 15, -17],
"locators": {
"target": [0, 15, -17]
}
},
{
"name": "body",
"parent": "manectric",
@@ -44,14 +52,6 @@
"middle": [0, 17, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 18, -19],
"locators": {
"target": [0, 18, -19]
}
},
{
"name": "hips",
"parent": "body",
@@ -16,144 +16,445 @@
"pivot": [0, 0, 0]
},
{
"name": "body",
"name": "locator_root",
"parent": "elgyem",
"pivot": [0, 5.5, 0.25]
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "torso_medium",
"name": "locator_top",
"parent": "elgyem",
"pivot": [0, 24, 0],
"locators": {
"top": [0, 24, 0]
}
},
{
"name": "body",
"parent": "elgyem",
"pivot": [0, 5.75, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 5, 1.75],
"pivot": [0, 9, -6],
"locators": {
"target": [0, 9, -6]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 10, 0],
"locators": {
"middle": [0, 10, 0]
}
},
{
"name": "torso_middle",
"parent": "body",
"pivot": [0, 5.25, 1.75],
"cubes": [
{"origin": [-1.5, 4.75, -1.25], "size": [3, 2, 3], "uv": [39, 4]}
{"origin": [-1.5, 5, -1.25], "size": [3, 2, 3], "uv": [39, 4]}
]
},
{
"name": "torso_top",
"parent": "torso_medium",
"pivot": [0, 6.25, 1],
"parent": "torso_middle",
"pivot": [0, 6.5, 1],
"cubes": [
{"origin": [-1, 6, -1], "size": [2, 3, 2], "uv": [49, 11]}
{"origin": [-1, 6.25, -1], "size": [2, 4, 2], "uv": [39, 13]}
]
},
{
"name": "head",
"parent": "torso_top",
"pivot": [0, 9, 0],
"pivot": [0, 9.25, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 9.25, 0]
},
{
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 9.25, 0],
"cubes": [
{"origin": [-3.5, 9, -3.25], "size": [7, 11, 6], "uv": [0, 0]},
{"origin": [-3.5, 11.5, -3.25], "size": [7, 1, 6], "inflate": 0.01, "uv": [0, 17]}
{"origin": [-3.5, 9.25, -3.25], "size": [7, 11, 6], "uv": [0, 0]},
{"origin": [-3.5, 11.75, -3.25], "size": [7, 1, 6], "inflate": 0.01, "uv": [0, 17]}
]
},
{
"name": "locator_item_hat",
"parent": "head_angle",
"pivot": [0, 19.5, -0.25],
"locators": {
"item_hat": [0, 19.5, -0.25]
}
},
{
"name": "locator_head",
"parent": "head_angle",
"pivot": [0, 19.25, -3.25],
"locators": {
"head": [0, 19.25, -3.25]
}
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 11, -3.25],
"locators": {
"item_face": [0, 11, -3.25]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 11.25, -3.25],
"locators": {
"face": [0, 11.25, -3.25]
}
},
{
"name": "eyes",
"parent": "head_angle",
"pivot": [0, 10.75, -3.25]
},
{
"name": "eye_right",
"parent": "head",
"pivot": [-1.25, 10.5, -3.25],
"parent": "eyes",
"pivot": [-1.5, 10.75, -3.25],
"cubes": [
{"origin": [-1.75, 9.5, -3.265], "size": [1, 2, 0], "uv": [4, 17]}
{"origin": [-2, 9.75, -3.265], "size": [1, 2, 0], "uv": [43, 1]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-1.5, 10.75, -3.25],
"locators": {
"eye1": [-1.5, 10.75, -3.25]
}
},
{
"name": "eye_bright_right",
"parent": "eye_right",
"pivot": [-1.5, 10.75, -3.15],
"cubes": [
{"origin": [-2, 9.75, -3.165], "size": [1, 2, 0], "inflate": 0.01, "uv": [49, 1]}
]
},
{
"name": "eye_left",
"parent": "head",
"pivot": [1.25, 10.5, -3.25],
"parent": "eyes",
"pivot": [1.5, 10.75, -3.25],
"cubes": [
{"origin": [0.75, 9.5, -3.265], "size": [1, 2, 0], "uv": [4, 0]}
{"origin": [1, 9.75, -3.265], "size": [1, 2, 0], "uv": [40, 1]}
]
},
{
"name": "arm_right",
"parent": "torso_top",
"pivot": [-1, 8.5, 0],
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [1.5, 10.75, -3.25],
"locators": {
"eye2": [1.5, 10.75, -3.25]
}
},
{
"name": "eye_bright_left",
"parent": "eye_left",
"pivot": [1.5, 10.75, -3.15],
"cubes": [
{"origin": [-4.5, 7.5, -0.5], "size": [4, 1, 1], "uv": [38, 11]}
{"origin": [1, 9.75, -3.165], "size": [1, 2, 0], "inflate": 0.01, "uv": [46, 1]}
]
},
{
"name": "arms",
"parent": "torso_top",
"pivot": [0, 8.75, 0]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-1, 8.75, 0],
"cubes": [
{"origin": [-4.5, 7.75, -0.5], "size": [4, 1, 1], "uv": [38, 11]}
]
},
{
"name": "forearm_right",
"parent": "arm_right",
"pivot": [-4, 8, 0],
"pivot": [-4, 8.25, 0],
"cubes": [
{"origin": [-6, 7, -1], "size": [2, 2, 2], "uv": [44, 0]}
{"origin": [-7, 7.25, -1], "size": [3, 2, 2], "uv": [47, 11]}
]
},
{
"name": "hand_right",
"parent": "forearm_right",
"pivot": [-6, 8, 0],
"pivot": [-7, 9.25, 0],
"cubes": [
{"origin": [-9, 7, -1.5], "size": [3, 2, 3], "inflate": 0.01, "uv": [26, 11]},
{"origin": [-8.75, 6.5, -0.5], "size": [1, 1, 1], "uv": [0, 17]},
{"origin": [-7.25, 6.5, 0.25], "size": [1, 1, 1], "uv": [0, 19]},
{"origin": [-7.25, 6.5, -1.25], "size": [1, 1, 1], "uv": [0, 21]}
{"origin": [-9, 7.25, -1.5], "size": [3, 2, 3], "inflate": 0.01, "uv": [26, 11]}
]
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-7.5, 7.25, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-7.5, 7.25, 0],
"physical": [-7.5, 7.25, 0],
"special": [-7.5, 7.25, 0]
}
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-7.5, 6.5, -0.5],
"locators": {
"item": [-7.5, 6.5, -0.5]
}
},
{
"name": "fingers_right",
"parent": "hand_right",
"pivot": [-7.25, 7.25, 0]
},
{
"name": "right_finger_dim_green",
"parent": "fingers_right",
"pivot": [-6.75, 7.25, -0.75],
"cubes": [
{"origin": [-7.25, 6.75, -1.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [5, 29]}
]
},
{
"name": "right_finger_bright_green",
"parent": "right_finger_dim_green",
"pivot": [-6.75, 7.25, -0.75],
"cubes": [
{"origin": [-7.25, 6.75, -1.25], "size": [1, 1, 1], "uv": [10, 29]}
]
},
{
"name": "right_finger_dim_red",
"parent": "fingers_right",
"pivot": [-8.25, 7.25, 0],
"cubes": [
{"origin": [-8.75, 6.75, -0.5], "size": [1, 1, 1], "inflate": 0.01, "uv": [5, 25]}
]
},
{
"name": "right_finger_bright_red",
"parent": "right_finger_dim_red",
"pivot": [-8.25, 7.25, 0],
"cubes": [
{"origin": [-8.75, 6.75, -0.5], "size": [1, 1, 1], "uv": [10, 25]}
]
},
{
"name": "right_finger_dim_yellow",
"parent": "fingers_right",
"pivot": [-6.75, 7.25, 0.75],
"cubes": [
{"origin": [-7.25, 6.75, 0.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [5, 27]}
]
},
{
"name": "right_finger_bright_yellow",
"parent": "right_finger_dim_yellow",
"pivot": [-6.75, 7.25, 0.75],
"cubes": [
{"origin": [-7.25, 6.75, 0.25], "size": [1, 1, 1], "uv": [10, 27]}
]
},
{
"name": "arm_left",
"parent": "torso_top",
"pivot": [1, 8.5, 0],
"parent": "arms",
"pivot": [1, 8.75, 0],
"cubes": [
{"origin": [0.5, 7.5, -0.5], "size": [4, 1, 1], "uv": [38, 9]}
{"origin": [0.5, 7.75, -0.5], "size": [4, 1, 1], "uv": [38, 9]}
]
},
{
"name": "forearm_left",
"parent": "arm_left",
"pivot": [4, 8, 0],
"pivot": [4, 8.25, 0],
"cubes": [
{"origin": [4, 7, -1], "size": [2, 2, 2], "uv": [36, 0]}
{"origin": [4, 7.25, -1], "size": [3, 2, 2], "uv": [47, 15]}
]
},
{
"name": "hand_left",
"parent": "forearm_left",
"pivot": [6, 8, 0],
"pivot": [7, 9.25, 0],
"cubes": [
{"origin": [6, 7, -1.5], "size": [3, 2, 3], "inflate": 0.01, "uv": [26, 6]},
{"origin": [7.75, 6.5, -0.5], "size": [1, 1, 1], "uv": [0, 0]},
{"origin": [6.25, 6.5, 0.25], "size": [1, 1, 1], "uv": [0, 2]},
{"origin": [6.25, 6.5, -1.25], "size": [1, 1, 1], "uv": [0, 4]}
{"origin": [6, 7.25, -1.5], "size": [3, 2, 3], "inflate": 0.01, "uv": [26, 6]}
]
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [7.5, 7.25, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [7.5, 7.25, 0]
}
},
{
"name": "fingers_left",
"parent": "hand_left",
"pivot": [7.25, 7.25, 0]
},
{
"name": "left_finger_dim_green",
"parent": "fingers_left",
"pivot": [6.75, 7.25, -0.75],
"cubes": [
{"origin": [6.25, 6.75, -1.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [1, 29]}
]
},
{
"name": "left_finger_bright_green",
"parent": "left_finger_dim_green",
"pivot": [6.75, 7.25, -0.75],
"cubes": [
{"origin": [6.25, 6.75, -1.25], "size": [1, 1, 1], "uv": [14, 29]}
]
},
{
"name": "left_finger_dim_red",
"parent": "fingers_left",
"pivot": [8.25, 7.25, 0],
"cubes": [
{"origin": [7.75, 6.75, -0.5], "size": [1, 1, 1], "inflate": 0.01, "uv": [1, 25]}
]
},
{
"name": "left_finger_bright_red2",
"parent": "left_finger_dim_red",
"pivot": [8.25, 7.25, 0],
"cubes": [
{"origin": [7.75, 6.75, -0.5], "size": [1, 1, 1], "uv": [14, 25]}
]
},
{
"name": "left_finger_dim_yellow",
"parent": "fingers_left",
"pivot": [6.75, 7.25, 0.75],
"cubes": [
{"origin": [6.25, 6.75, 0.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [1, 27]}
]
},
{
"name": "left_finger_bright_yellow",
"parent": "left_finger_dim_yellow",
"pivot": [6.75, 7.25, 0.75],
"cubes": [
{"origin": [6.25, 6.75, 0.25], "size": [1, 1, 1], "uv": [14, 27]}
]
},
{
"name": "torso_bottom",
"parent": "body",
"pivot": [0, 5.5, 1.75],
"pivot": [0, 5.75, 1.75],
"cubes": [
{"origin": [-2, 2.5, -1.5], "size": [4, 3, 4], "uv": [48, 0]}
{"origin": [-2, 2.75, -1.5], "size": [4, 3, 4], "uv": [48, 0]}
]
},
{
"name": "tail",
"parent": "torso_bottom",
"pivot": [0, 2.5, 1.5],
"pivot": [0, 3.75, 1.5],
"cubes": [
{"origin": [-1, 2.5, 1.25], "size": [2, 2, 2], "inflate": 0.01, "uv": [49, 7]}
{"origin": [-1, 2.75, 1.25], "size": [2, 2, 2], "inflate": 0.01, "uv": [49, 7]}
]
},
{
"name": "tail_tip",
"name": "locator_tail",
"parent": "tail",
"pivot": [0, 3.5, 3.25],
"pivot": [0, 3.75, 3.25],
"rotation": [-180, 0, 180],
"locators": {
"tail": [0, 3.75, 3.25]
}
},
{
"name": "tail2",
"parent": "tail",
"pivot": [0, 3.75, 3.25],
"cubes": [
{"origin": [-0.5, 3, 3], "size": [1, 1, 2], "uv": [36, 4]}
{"origin": [-0.5, 3.25, 3], "size": [1, 1, 2], "uv": [36, 4]}
]
},
{
"name": "locator_tail_tip",
"parent": "tail2",
"pivot": [0, 3.75, 5],
"rotation": [-180, 0, 180],
"locators": {
"tail_tip": [0, 3.75, 5]
}
},
{
"name": "legs",
"parent": "torso_bottom",
"pivot": [0, 3.25, -0.25]
},
{
"name": "leg_right",
"parent": "torso_bottom",
"pivot": [-1.25, 3.25, 0.25],
"parent": "legs",
"pivot": [-1.25, 3.25, -0.25],
"cubes": [
{"origin": [-2.5, 0, -0.75], "size": [2, 4, 2], "uv": [28, 0]}
{"origin": [-2.5, 2, -1.25], "size": [2, 2, 2], "inflate": 0.01, "uv": [28, 20]}
]
},
{
"name": "leg_left",
"parent": "torso_bottom",
"pivot": [1.25, 3.25, 0.25],
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-1.5, 2, -1.25],
"cubes": [
{"origin": [0.5, 0, -0.75], "size": [2, 4, 2], "uv": [20, 0]}
{"origin": [-2.5, 0, -1.25], "size": [2, 2, 2], "uv": [28, 16]}
]
},
{
"name": "locator_foot_primary",
"parent": "leg_right2",
"pivot": [-1.5, 0.5, -0.3],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-1.5, 0.5, -0.3]
}
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [1.25, 3.25, -0.25],
"cubes": [
{"origin": [0.5, 2, -1.25], "size": [2, 2, 2], "inflate": 0.01, "uv": [20, 2]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [1.5, 2, -1.25],
"cubes": [
{"origin": [0.5, 0, -1.25], "size": [2, 2, 2], "uv": [28, 2]}
]
},
{
"name": "locator_foot_secondary",
"parent": "leg_left2",
"pivot": [1.5, 0.5, -0.3],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [1.5, 0.5, -0.3]
}
}
]
}
@@ -4,8 +4,8 @@
{
"description": {
"identifier": "geometry.beheeyem",
"texture_width": 128,
"texture_height": 32,
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
@@ -15,160 +15,442 @@
"name": "beheeyem",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "beheeyem",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "beheeyem",
"pivot": [0, 31, 0],
"locators": {
"top": [0, 31, 0]
}
},
{
"name": "body",
"parent": "beheeyem",
"pivot": [0, 7, 0]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 11, 0],
"locators": {
"middle": [0, 11, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 10, -8],
"locators": {
"target": [0, 10, -8]
}
},
{
"name": "torso_top",
"parent": "body",
"pivot": [-1.25, 7.25, 2],
"pivot": [0.25, 7.25, 0],
"cubes": [
{"origin": [-2, 7.22906, -2.00011], "size": [4, 6, 4], "uv": [35, 0]},
{"origin": [0.75, 7.97906, -2.32511], "size": [1, 1, 1], "pivot": [1.25, 8.47906, -1.92511], "rotation": [0, -5, 0], "uv": [81, 2]},
{"origin": [-1.75, 7.97906, -2.32511], "size": [1, 1, 1], "pivot": [-1.25, 8.47906, -1.92511], "rotation": [0, 5, 0], "uv": [95, 2]}
{"origin": [-2, 6.25, -2], "size": [4, 7, 4], "uv": [35, 0]},
{"origin": [0.75, 8.5, -2.3], "size": [1, 1, 1], "uv": [40, 58]},
{"origin": [-1.75, 8.5, -2.3], "size": [1, 1, 1], "uv": [36, 58]}
]
},
{
"name": "collar_back",
"parent": "torso_top",
"pivot": [0, 13.22906, -0.25011],
"pivot": [0, 12.23, -0.25],
"cubes": [
{"origin": [-2.5, 11.22906, -0.25011], "size": [5, 2, 3], "inflate": 0.01, "uv": [89, 14]}
{"origin": [-2.5, 11.25, -0.25], "size": [5, 2, 3], "inflate": 0.01, "uv": [48, 12]}
]
},
{
"name": "collar_front",
"parent": "collar_back",
"pivot": [0, 12.72906, -0.25011],
"rotation": [30, 0, 0],
"pivot": [0, 12.75, -0.25],
"cubes": [
{"origin": [-2.5, 11.72906, -3.25011], "size": [2, 1, 3], "uv": [50, 22]},
{"origin": [0.5, 11.72906, -3.25011], "size": [2, 1, 3], "uv": [60, 22]}
{"origin": [-2.5, 11.75, -3.25], "size": [2, 1, 3], "uv": [54, 17]},
{"origin": [0.5, 11.75, -3.25], "size": [2, 1, 3], "uv": [54, 21]}
]
},
{
"name": "head",
"parent": "torso_top",
"pivot": [0, 12.72906, -0.00011],
"pivot": [0, 12.73, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 12.73, 0]
},
{
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 12.73, 0],
"cubes": [
{"origin": [-4, 19.72906, -3.50011], "size": [8, 7, 7], "uv": [0, 14]},
{"origin": [-4.5, 16.72906, -4.50011], "size": [9, 3, 9], "uv": [92, 0]},
{"origin": [-6, 13.72906, -5.50011], "size": [12, 3, 11], "uv": [0, 0]},
{"origin": [-4, 12.72906, -3.50011], "size": [8, 1, 7], "uv": [98, 12]},
{"origin": [-0.5, 19.72906, -3.50011], "size": [1, 1, 1], "inflate": 0.005, "uv": [51, 5]},
{"origin": [-6, 14.22906, -5.50011], "size": [12, 1, 11], "inflate": 0.005, "uv": [46, 0]},
{"origin": [-5, 13.72906, -4.50011], "size": [10, 1, 9], "inflate": 0.005, "uv": [37, 12]},
{"origin": [-4, 13.22906, -3.50011], "size": [8, 1, 7], "inflate": 0.005, "uv": [66, 12]}
{"origin": [-4, 19.75, -4], "size": [8, 7, 7], "uv": [0, 14]},
{"origin": [-4.5, 16.75, -5], "size": [9, 3, 9], "uv": [0, 28]},
{"origin": [-6, 13.75, -6], "size": [12, 3, 11], "uv": [0, 0]},
{"origin": [-4, 12.75, -4], "size": [8, 1, 7], "uv": [23, 40]},
{"origin": [-0.5, 19.75, -4], "size": [1, 1, 0], "inflate": 0.005, "uv": [48, 1]},
{"origin": [-6, 14.25, -6], "size": [12, 1, 11], "inflate": 0.005, "uv": [0, 52]},
{"origin": [-4, 13.25, -4], "size": [8, 1, 7], "inflate": 0.005, "uv": [0, 44]}
]
},
{
"name": "locator_item_hat",
"parent": "head_angle",
"pivot": [0, 25.75, -0.5],
"locators": {
"item_hat": [0, 25.75, -0.5]
}
},
{
"name": "locator_head",
"parent": "head_angle",
"pivot": [0, 22.75, -4],
"locators": {
"head": [0, 22.75, -4]
}
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 15, -5.9],
"locators": {
"item_face": [0, 15, -5.9]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 14.85, -6],
"locators": {
"face": [0, 14.85, -6]
}
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 14.72906, -5.50011],
"parent": "head_angle",
"pivot": [0, 14.75, -6]
},
{
"name": "eyes_bright",
"parent": "eyes",
"pivot": [0, 14.85, -5.9],
"cubes": [
{"origin": [-4, 14.22906, -5.51511], "size": [8, 1, 0], "uv": [35, 10]},
{"origin": [-3, 13.72906, -5.51011], "size": [2, 2, 0], "uv": [51, 7]},
{"origin": [1, 13.72906, -5.51011], "size": [2, 2, 0], "uv": [51, 9]},
{"origin": [-2.5, 13.72906, -5.52011], "size": [1, 2, 0], "uv": [55, 7]},
{"origin": [1.5, 13.72906, -5.52011], "size": [1, 2, 0], "uv": [55, 9]},
{"origin": [-2.5, 14.22906, -5.52511], "size": [1, 1, 0], "uv": [55, 5]},
{"origin": [1.5, 14.22906, -5.52511], "size": [1, 1, 0], "uv": [55, 6]}
{"origin": [-4, 14.35, -5.91], "size": [8, 1, 0], "uv": [47, 45]},
{"origin": [-3, 13.85, -5.915], "size": [2, 2, 0], "uv": [1, 4]},
{"origin": [1, 13.85, -5.915], "size": [2, 2, 0], "uv": [6, 4]}
]
},
{
"name": "arm_right",
"parent": "torso_top",
"pivot": [-2, 10.97906, -0.00011],
"name": "eyes_dim",
"parent": "eyes",
"pivot": [0, 14.85, -6],
"cubes": [
{"origin": [-6.5, 10.47906, -0.50011], "size": [5, 1, 1], "uv": [87, 20]}
{"origin": [-4, 14.35, -6.01], "size": [8, 1, 0], "uv": [47, 43]},
{"origin": [-3, 13.85, -6.015], "size": [2, 2, 0], "uv": [1, 1]},
{"origin": [1, 13.85, -6.015], "size": [2, 2, 0], "uv": [6, 1]}
]
},
{
"name": "pupil_left",
"parent": "eyes",
"pivot": [2, 14.85, -6],
"cubes": [
{"origin": [1.5, 14.35, -6.02], "size": [1, 1, 0], "uv": [6, 7]}
]
},
{
"name": "locator_eye_left",
"parent": "pupil_left",
"pivot": [2, 14.85, -6],
"locators": {
"eye2": [2, 14.85, -6]
}
},
{
"name": "pupil_right",
"parent": "eyes",
"pivot": [-2, 14.85, -6.01],
"cubes": [
{"origin": [-2.5, 14.35, -6.02], "size": [1, 1, 0], "uv": [1, 7]}
]
},
{
"name": "locator_eye_right",
"parent": "pupil_right",
"pivot": [-2, 14.85, -6],
"locators": {
"eye1": [-2, 14.85, -6]
}
},
{
"name": "arms",
"parent": "torso_top",
"pivot": [0, 11, 0]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-2, 11, -0.00011],
"cubes": [
{"origin": [-5.5, 10.5, -0.5], "size": [4, 1, 1], "uv": [27, 35]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-6, 10.97906, -0.00011],
"pivot": [-5, 11, 0],
"cubes": [
{"origin": [-9, 10.22906, -1.00011], "size": [3, 2, 2], "uv": [0, 4]}
{"origin": [-9, 10.25, -1], "size": [4, 2, 2], "uv": [23, 14]}
]
},
{
"name": "hand_right",
"parent": "arm_right2",
"pivot": [-8.5, 10.97906, -0.00011],
"pivot": [-8.5, 11.25, 0],
"cubes": [
{"origin": [-10.5, 10.22906, -1.50011], "size": [2, 3, 3], "inflate": 0.01, "uv": [30, 22]},
{"origin": [-11, 10.37906, 0.27489], "size": [1, 1, 1], "uv": [119, 2]},
{"origin": [-11, 12.07906, -0.50011], "size": [1, 1, 1], "uv": [119, 0]},
{"origin": [-11, 10.37906, -1.27511], "size": [1, 1, 1], "uv": [119, 4]}
{"origin": [-11, 10, -1.5], "size": [3, 3, 3], "inflate": 0.01, "uv": [51, 6]}
]
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-11, 11.5, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-11, 11.5, 0],
"physical": [-11, 11.5, 0],
"special": [-11, 11.5, 0]
}
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-11.75, 11.25, 0],
"rotation": [-90, 0, 0],
"locators": {
"item": [-11.75, 11.25, 0]
}
},
{
"name": "right_fingers",
"parent": "hand_right",
"pivot": [-11, 10.75, 0.75]
},
{
"name": "right_finger_dim_green",
"parent": "right_fingers",
"pivot": [-11, 10.75, -0.75],
"cubes": [
{"origin": [-11.5, 10.25, -1.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [55, 40]}
]
},
{
"name": "right_finger_bright_green2",
"parent": "right_finger_dim_green",
"pivot": [-11, 10.75, -0.75],
"cubes": [
{"origin": [-11.5, 10.25, -1.25], "size": [1, 1, 1], "uv": [55, 33]}
]
},
{
"name": "right_finger_dim_red",
"parent": "right_fingers",
"pivot": [-11, 12.25, 0],
"cubes": [
{"origin": [-11.5, 11.75, -0.5], "size": [1, 1, 1], "inflate": 0.01, "uv": [55, 36]}
]
},
{
"name": "right_finger_bright_red2",
"parent": "right_finger_dim_red",
"pivot": [-11, 12.25, 0],
"cubes": [
{"origin": [-11.5, 11.75, -0.5], "size": [1, 1, 1], "uv": [55, 29]}
]
},
{
"name": "right_finger_dim_yellow",
"parent": "right_fingers",
"pivot": [-11, 10.75, 0.75],
"cubes": [
{"origin": [-11.5, 10.25, 0.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [55, 38]}
]
},
{
"name": "right_finger_bright_yellow",
"parent": "right_finger_dim_yellow",
"pivot": [-11, 10.75, 0.75],
"cubes": [
{"origin": [-11.5, 10.25, 0.25], "size": [1, 1, 1], "uv": [55, 31]}
]
},
{
"name": "arm_left",
"parent": "torso_top",
"pivot": [2, 10.97906, -0.00011],
"parent": "arms",
"pivot": [2, 11, 0],
"cubes": [
{"origin": [1.5, 10.47906, -0.50011], "size": [5, 1, 1], "uv": [75, 20]}
{"origin": [1.5, 10.5, -0.5], "size": [4, 1, 1], "uv": [37, 35]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [6, 10.97906, -0.00011],
"pivot": [5, 11, 0],
"cubes": [
{"origin": [6, 10.22906, -1.00011], "size": [3, 2, 2], "uv": [0, 0]}
{"origin": [5, 10.25, -1], "size": [4, 2, 2], "uv": [35, 14]}
]
},
{
"name": "hand_left",
"parent": "arm_left2",
"pivot": [8.5, 10.97906, -0.00011],
"pivot": [8.5, 11.25, 0],
"cubes": [
{"origin": [8.5, 10.22906, -1.50011], "size": [2, 3, 3], "inflate": 0.01, "uv": [40, 22]},
{"origin": [10, 10.37906, 0.27489], "size": [1, 1, 1], "uv": [124, 2]},
{"origin": [10, 12.07906, -0.50011], "size": [1, 1, 1], "uv": [124, 0]},
{"origin": [10, 10.37906, -1.27511], "size": [1, 1, 1], "uv": [124, 4]}
{"origin": [8, 10, -1.5], "size": [3, 3, 3], "inflate": 0.01, "uv": [51, 0]}
]
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [11, 11.5, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [11, 11.5, 0]
}
},
{
"name": "left_fingers",
"parent": "hand_left",
"pivot": [11, 10.75, 0.75]
},
{
"name": "left_finger_dim_green",
"parent": "left_fingers",
"pivot": [11, 10.75, -0.75],
"cubes": [
{"origin": [10.5, 10.25, -1.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [59, 40]}
]
},
{
"name": "left_finger_bright_green2",
"parent": "left_finger_dim_green",
"pivot": [11, 10.75, -0.75],
"cubes": [
{"origin": [10.5, 10.25, -1.25], "size": [1, 1, 1], "uv": [59, 33]}
]
},
{
"name": "left_finger_dim_red",
"parent": "left_fingers",
"pivot": [11, 12.25, 0],
"cubes": [
{"origin": [10.5, 11.75, -0.5], "size": [1, 1, 1], "inflate": 0.01, "uv": [59, 36]}
]
},
{
"name": "left_finger_bright_red2",
"parent": "left_finger_dim_red",
"pivot": [11, 12.25, 0],
"cubes": [
{"origin": [10.5, 11.75, -0.5], "size": [1, 1, 1], "uv": [59, 29]}
]
},
{
"name": "left_finger_dim_yellow",
"parent": "left_fingers",
"pivot": [11, 10.75, 0.75],
"cubes": [
{"origin": [10.5, 10.25, 0.25], "size": [1, 1, 1], "inflate": 0.01, "uv": [59, 38]}
]
},
{
"name": "left_finger_bright_yellow",
"parent": "left_finger_dim_yellow",
"pivot": [11, 10.75, 0.75],
"cubes": [
{"origin": [10.5, 10.25, 0.25], "size": [1, 1, 1], "uv": [59, 31]}
]
},
{
"name": "torso_bottom",
"parent": "body",
"pivot": [0, 7.25, 2],
"pivot": [0, 7.25, 0],
"cubes": [
{"origin": [-2.5, 3.25, -2], "size": [5, 4, 4], "uv": [81, 0]},
{"origin": [-1.75, 5.5, -2.275], "size": [1, 1, 1], "pivot": [-1.25, 6, -1.875], "rotation": [0, 5, 0], "uv": [81, 0]},
{"origin": [0.75, 5.5, -2.275], "size": [1, 1, 1], "pivot": [1.25, 6, -1.875], "rotation": [0, -5, 0], "uv": [95, 0]}
{"origin": [-2.5, 3.75, -2.5], "size": [5, 4, 5], "inflate": 0.01, "uv": [27, 26]},
{"origin": [-1.75, 6, -2.8], "size": [1, 1, 1], "uv": [36, 60]},
{"origin": [0.75, 6, -2.8], "size": [1, 1, 1], "uv": [40, 60]}
]
},
{
"name": "bottom_coat",
"parent": "torso_bottom",
"pivot": [0, 5, -2],
"rotation": [-17.5, 0, 0],
"pivot": [0, 4.75, -2.6],
"cubes": [
{"origin": [-4, 3, -2], "size": [0, 2, 6], "uv": [100, 14]},
{"origin": [-4, 3, -2], "size": [8, 2, 0], "uv": [112, 20]},
{"origin": [4, 3, -2], "size": [0, 2, 6], "uv": [100, 16]},
{"origin": [-4, 3, 4], "size": [8, 2, 0], "uv": [112, 22]},
{"origin": [-4, 5, -2], "size": [8, 0, 6], "uv": [106, 24]}
{"origin": [-4, 2.75, -2.6], "size": [0, 2, 7], "uv": [50, 44]},
{"origin": [-4, 2.75, -2.6], "size": [8, 2, 0], "uv": [48, 53]},
{"origin": [4, 2.75, -2.6], "size": [0, 2, 7], "uv": [50, 42]},
{"origin": [-4, 2.75, 4.4], "size": [8, 2, 0], "uv": [48, 55]},
{"origin": [-4, 4.75, -2.6], "size": [8, 0, 7], "uv": [41, 57]}
]
},
{
"name": "leg_right",
"parent": "torso_bottom",
"pivot": [-1.25, 3.25, 0],
"pivot": [-1.5, 3.25, 0],
"cubes": [
{"origin": [-2.25, 0, -1], "size": [2, 4, 2], "uv": [23, 15]}
{"origin": [-2.5, 2, -1], "size": [2, 2, 2], "inflate": 0.01, "uv": [30, 18]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-1.5, 2, -1],
"cubes": [
{"origin": [-2.5, 0, -1], "size": [2, 2, 2], "uv": [30, 22]}
]
},
{
"name": "locator_foot_primary",
"parent": "leg_right2",
"pivot": [-1.5, 0.5, 0],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-1.5, 0.5, 0]
}
},
{
"name": "leg_left",
"parent": "torso_bottom",
"pivot": [1.25, 3.25, 0],
"pivot": [1.5, 3.25, 0],
"cubes": [
{"origin": [0.25, 0, -1], "size": [2, 4, 2], "uv": [38, 15]}
{"origin": [0.5, 2, -1], "size": [2, 2, 2], "inflate": 0.01, "uv": [38, 18]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [1.5, 2, -1],
"cubes": [
{"origin": [0.5, 0, -1], "size": [2, 2, 2], "uv": [38, 22]}
]
},
{
"name": "locator_foot_secondary",
"parent": "leg_left2",
"pivot": [1.5, 0.5, 0],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [1.5, 0.5, 0]
}
}
]
}
@@ -18,136 +18,179 @@
{
"name": "body",
"parent": "litwick",
"pivot": [0, 0, 0]
},
{
"name": "wax_trail",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-4, 0.015, -4], "size": [8, 0, 8], "uv": [0, 0]}
]
},
{
"name": "wax_trail2",
"parent": "wax_trail",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-4, 0.02, 0], "size": [8, 0, 4], "uv": [14, 8]}
]
"pivot": [0, 4.5, 0]
},
{
"name": "head",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-3, 0, -3], "size": [6, 7, 6], "uv": [0, 8]}
{"origin": [-3.5, 0.015, -3.5], "size": [7, 2, 7], "inflate": -0.01, "uv": [0, 16]}
]
},
{
"name": "head2",
"parent": "head",
"pivot": [0, 1.5, 0],
"cubes": [
{"origin": [-4, 1.25, -4], "size": [8, 8, 8], "inflate": -0.1, "uv": [0, 0]}
]
},
{
"name": "eyes",
"parent": "head2",
"pivot": [0, 4, -3.9]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.45, 4, -3.91]
},
{
"name": "eye_left_open",
"parent": "eye_left",
"pivot": [2.45, 4, -3.91],
"cubes": [
{"origin": [1.95, 3, -3.91], "size": [1, 2, 0], "uv": [0, 0]}
]
},
{
"name": "eye_expression_left",
"parent": "eye_left_open",
"pivot": [2.45, 5, -3.82],
"cubes": [
{"origin": [1.95, 4.5, -3.82], "size": [1, 1, 0], "uv": [2, 0]}
]
},
{
"name": "eye_closed_left",
"parent": "eye_left",
"pivot": [2.45, 4, -3.81],
"cubes": [
{"origin": [1.45, 3.5, -3.81], "size": [2, 1, 0], "uv": [4, 0]}
]
},
{
"name": "eye_happy_left",
"parent": "eye_left",
"pivot": [2.45, 4.5, -3.81],
"cubes": [
{"origin": [1.45, 4, -3.81], "size": [2, 1, 0], "uv": [4, 2]},
{"origin": [1.95, 3.5, -3.82], "size": [1, 1, 0], "uv": [2, 2]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.45, 4, -3.91]
},
{
"name": "eye_right_open",
"parent": "eye_right",
"pivot": [-2.45, 4, -3.91],
"cubes": [
{"origin": [-2.95, 3, -3.91], "size": [1, 2, 0], "uv": [0, 2], "mirror": true}
]
},
{
"name": "eye_expression_right",
"parent": "eye_right_open",
"pivot": [-2.45, 5, -3.82],
"cubes": [
{"origin": [-2.95, 4.5, -3.82], "size": [1, 1, 0], "uv": [2, 1], "mirror": true}
]
},
{
"name": "eye_closed_right",
"parent": "eye_right",
"pivot": [-2.45, 4, -3.81],
"cubes": [
{"origin": [-3.45, 3.5, -3.81], "size": [2, 1, 0], "uv": [4, 1], "mirror": true}
]
},
{
"name": "eye_happy_right",
"parent": "eye_right",
"pivot": [-2.45, 4.5, -3.81],
"cubes": [
{"origin": [-3.45, 4, -3.81], "size": [2, 1, 0], "uv": [4, 3], "mirror": true},
{"origin": [-2.95, 3.5, -3.82], "size": [1, 1, 0], "uv": [2, 3], "mirror": true}
]
},
{
"name": "mouth",
"parent": "head2",
"pivot": [0, 3.5, -3.9]
},
{
"name": "mouth_rotation",
"parent": "mouth",
"pivot": [0, 3.5, -3.9],
"rotation": [-25, 0, 0],
"cubes": [
{"origin": [-1, 2.5, -3.9], "size": [2, 1, 1], "uv": [24, 2]}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 2.5, -3.8],
"cubes": [
{"origin": [-1, 2, -3.81], "size": [2, 1, 0], "uv": [4, 7]}
]
},
{
"name": "hair",
"parent": "head",
"pivot": [0, 9.5, 0],
"parent": "head2",
"pivot": [0, 9, 0],
"cubes": [
{"origin": [-3.5, 7.5, -3.5], "size": [7, 0, 7], "uv": [17, 0]},
{"origin": [-3.5, 2.5, -3.5], "size": [7, 5, 0], "uv": [0, 26]},
{"origin": [-3.5, 2.5, -3.5], "size": [0, 5, 7], "uv": [14, 14]},
{"origin": [3.5, 2.5, -3.5], "size": [0, 5, 7], "uv": [0, 14]},
{"origin": [-3.5, 2.5, 3.5], "size": [7, 5, 0], "uv": [24, 12]}
{"origin": [-4.5, 2.5, -4.5], "size": [9, 7, 9], "inflate": 0.01, "uv": [23, 7]}
]
},
{
"name": "flame",
"parent": "hair",
"pivot": [0, 7.5, 0],
"pivot": [0, 9.5, 0],
"cubes": [
{"origin": [-2, 7, 0], "size": [4, 5, 0], "uv": [0, 0]},
{"origin": [0, 7, -2], "size": [0, 5, 4], "uv": [14, 22]}
{"origin": [-3, 9.5, 0], "size": [6, 8, 0], "pivot": [0, 13, 0], "rotation": [0, 45, 0], "uv": [51, 8]},
{"origin": [0, 9.5, -3], "size": [0, 8, 6], "pivot": [0, 13, 0], "rotation": [0, 45, 0], "uv": [51, -6]}
]
},
{
"name": "arms",
"parent": "head2",
"pivot": [0, 2.5, 0]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [4, 2.75, 0],
"cubes": [
{"origin": [3.75, 2, -0.5], "size": [2, 1, 1], "inflate": 0.1, "uv": [24, 4]}
]
},
{
"name": "arm_right",
"parent": "head",
"pivot": [-3, 2, -0.5],
"rotation": [0, 0, -90],
"parent": "arms",
"pivot": [-4, 2.75, 0],
"cubes": [
{"origin": [-3, 2, -2], "size": [0, 2, 2], "uv": [18, 10]}
{"origin": [-5.75, 2, -0.5], "size": [2, 1, 1], "inflate": 0.1, "uv": [24, 6], "mirror": true}
]
},
{
"name": "arm_left",
"parent": "head",
"pivot": [3, 2, -0.5],
"rotation": [0, 0, -90],
"name": "wax_trail",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [3, 0, -2], "size": [0, 2, 2], "uv": [0, 9]}
{"origin": [-5.5, 0.015, -5.5], "size": [11, 0, 7], "uv": [21, 23]}
]
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 4.5, -4]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2, 2.5, -3],
"name": "wax_trail2",
"parent": "wax_trail",
"pivot": [0, 0, 1.5],
"cubes": [
{"origin": [-2.5, 2.5, -3.01], "size": [1, 1, 0], "uv": [6, 6]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-1.9, 2.5, -2.9],
"cubes": [
{"origin": [-2.9, 2.5, -2.91], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 8]}
]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2, 2.5, -3],
"cubes": [
{"origin": [1.5, 2.5, -3.01], "size": [1, 1, 0], "uv": [5, 5]}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [1.9, 2.5, -2.9],
"cubes": [
{"origin": [0.9, 2.5, -2.91], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 5]}
]
},
{
"name": "mouth",
"parent": "head",
"pivot": [0, 2.5, -3]
},
{
"name": "lip",
"parent": "mouth",
"pivot": [0, 2.5, -3],
"rotation": [-5, 0, 0],
"cubes": [
{"origin": [-1, 1.5, -3.01], "size": [2, 1, 0], "uv": [24, 7]}
]
},
{
"name": "mouth_small",
"parent": "mouth",
"pivot": [0, 2.5, -3],
"cubes": [
{"origin": [-1, 1.5, -3.01], "size": [2, 1, 0], "uv": [0, 13]}
]
},
{
"name": "mouth_large",
"parent": "mouth",
"pivot": [0, 2.5, -2.9],
"cubes": [
{"origin": [-1, 0.5, -2.91], "size": [2, 2, 0], "uv": [24, 17]}
{"origin": [-4.5, 0.02, 1.5], "size": [9, 0, 5], "uv": [5, 26]}
]
}
]
@@ -4,11 +4,11 @@
{
"description": {
"identifier": "geometry.lampent",
"texture_width": 64,
"texture_width": 128,
"texture_height": 64,
"visible_bounds_width": 4,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
"visible_bounds_width": 5,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
@@ -18,16 +18,134 @@
{
"name": "body",
"parent": "lampent",
"pivot": [0, 0, 0]
"pivot": [0, 6, 0]
},
{
"name": "swing",
"parent": "body",
"pivot": [0, 21, 0],
"cubes": [
{"origin": [-1.5, 1.5, -1.5], "size": [3, 2, 3], "pivot": [0, 0, 0], "rotation": [0, -45, 0], "uv": [30, 16]},
{"origin": [-1, 0, -1], "size": [2, 1, 2], "pivot": [0, 0, 0], "rotation": [0, -45, 0], "uv": [0, 31]},
{"origin": [-2.5, 1, -2.5], "size": [5, 1, 5], "pivot": [0, 0, 0], "rotation": [0, -45, 0], "uv": [27, 28]}
{"origin": [-1, 0.5, -1], "size": [2, 1, 2], "uv": [120, 11]},
{"origin": [-3, 1.35, -3], "size": [6, 1, 6], "inflate": 0.1, "uv": [104, 16]},
{"origin": [-1.5, 2, -1.5], "size": [3, 2, 3], "inflate": -0.1, "uv": [116, 1]},
{"origin": [-2.5, 3.69, -2.5], "size": [5, 1, 5], "inflate": -0.1, "uv": [96, 0]}
]
},
{
"name": "arms",
"parent": "swing",
"pivot": [0, 3.5, 0]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [2.125, 3.5, 0],
"cubes": [
{"origin": [1.125, 3.5, -0.5], "size": [3, 0, 1], "uv": [59, 20]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [4.125, 3.5, 0],
"cubes": [
{"origin": [4.125, 3.5, -0.5], "size": [3, 0, 1], "uv": [65, 20]}
]
},
{
"name": "arm_left3",
"parent": "arm_left2",
"pivot": [7.125, 3.5, 0],
"cubes": [
{"origin": [7.125, 3.5, -1], "size": [4, 0, 2], "uv": [70, 18]}
]
},
{
"name": "arm_left4",
"parent": "arm_left3",
"pivot": [11.125, 3.5, 0],
"cubes": [
{"origin": [11.125, 3.5, -1], "size": [4, 0, 2], "uv": [78, 18]}
]
},
{
"name": "arm_left5",
"parent": "arm_left4",
"pivot": [15.125, 3.5, 0],
"cubes": [
{"origin": [15.125, 3.5, -1], "size": [3, 0, 2], "uv": [86, 18]}
]
},
{
"name": "arm_left6",
"parent": "arm_left5",
"pivot": [18.125, 3.5, 0],
"cubes": [
{"origin": [18.125, 3.5, -1.5], "size": [3, 0, 3], "uv": [91, 18]}
]
},
{
"name": "arm_left7",
"parent": "arm_left6",
"pivot": [21.125, 3.5, 0],
"cubes": [
{"origin": [21.125, 3.5, -1.5], "size": [3, 0, 3], "uv": [91, 21]}
]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-2.125, 3.5, 0],
"cubes": [
{"origin": [-4.125, 3.5, -0.5], "size": [3, 0, 1], "uv": [59, 21], "mirror": true}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-4.125, 3.5, 0],
"cubes": [
{"origin": [-7.125, 3.5, -0.5], "size": [3, 0, 1], "uv": [65, 21], "mirror": true}
]
},
{
"name": "arm_right3",
"parent": "arm_right2",
"pivot": [-7.125, 3.5, 0],
"cubes": [
{"origin": [-11.125, 3.5, -1], "size": [4, 0, 2], "uv": [70, 20], "mirror": true}
]
},
{
"name": "arm_right4",
"parent": "arm_right3",
"pivot": [-11.125, 3.5, 0],
"cubes": [
{"origin": [-15.125, 3.5, -1], "size": [4, 0, 2], "uv": [78, 20], "mirror": true}
]
},
{
"name": "arm_right5",
"parent": "arm_right4",
"pivot": [-15.125, 3.5, 0],
"cubes": [
{"origin": [-18.125, 3.5, -1], "size": [3, 0, 2], "uv": [86, 20], "mirror": true}
]
},
{
"name": "arm_right6",
"parent": "arm_right5",
"pivot": [-18.125, 3.5, 0],
"cubes": [
{"origin": [-21.125, 3.5, -1.5], "size": [3, 0, 3], "uv": [97, 18], "mirror": true}
]
},
{
"name": "arm_right7",
"parent": "arm_right6",
"pivot": [-21.125, 3.5, 0],
"cubes": [
{"origin": [-24.125, 3.5, -1.5], "size": [3, 0, 3], "uv": [97, 23], "mirror": true}
]
},
{
@@ -35,165 +153,112 @@
"parent": "swing",
"pivot": [0, 3.5, 0],
"cubes": [
{"origin": [-4.5, 3.5, -4.5], "size": [9, 6, 0], "uv": [42, 34]},
{"origin": [-4.5, 3.5, 4.5], "size": [9, 6, 0], "uv": [42, 40]},
{"origin": [-4.5, 3.5, -4.5], "size": [0, 6, 9], "uv": [42, 7]},
{"origin": [4.5, 3.5, -4.5], "size": [0, 6, 9], "uv": [42, 13]},
{"origin": [-4.5, 9.5, -4.5], "size": [9, 0, 9], "inflate": 0.01, "uv": [0, 28]},
{"origin": [-4.5, 3.5, -4.5], "size": [9, 0, 9], "inflate": 0.001, "uv": [33, 0]},
{"origin": [-4.5, 3.5, -4.5], "size": [9, 6, 9], "uv": [0, 37]}
]
},
{
"name": "flame",
"parent": "head",
"pivot": [0, 3.5, 0],
"cubes": [
{"origin": [-3, 3.5, 0], "size": [6, 6, 0], "pivot": [0, 3.5, 0], "rotation": [0, -45, 0], "uv": [0, 0]},
{"origin": [0, 3.5, -3], "size": [0, 6, 6], "pivot": [0, 3.5, 0], "rotation": [0, -45, 0], "uv": [0, 0]}
{"origin": [-5, 4.6, -5], "size": [10, 6, 0], "uv": [0, 20]},
{"origin": [-5, 4.6, 5], "size": [10, 6, 0], "uv": [0, 26]},
{"origin": [-5, 4.6, -5], "size": [10, 0, 10], "uv": [30, 20]},
{"origin": [5, 4.6, -5], "size": [0, 6, 10], "uv": [20, 10]},
{"origin": [-5, 4.6, -5], "size": [0, 6, 10], "uv": [20, 16], "mirror": true}
]
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 6, -4.5]
"pivot": [0, 7.5, -5]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [3, 7, -4.5],
"pivot": [3.2, 7.75, -5.01]
},
{
"name": "eye_left_open",
"parent": "eye_left",
"pivot": [3.2, 7.75, -5.01],
"cubes": [
{"origin": [2.5, 6, -4.5], "size": [1, 2, 0], "uv": [12, 0]}
{"origin": [2.7, 6.75, -5.01], "size": [1, 1, 0], "uv": [2, 16]}
]
},
{
"name": "eye_left_open2",
"parent": "eye_left_open",
"pivot": [3.2, 8.25, -5.02],
"cubes": [
{"origin": [2.7, 7.75, -5.01], "size": [1, 1, 0], "uv": [4, 16]}
]
},
{
"name": "eye_closed_left",
"parent": "eye_left",
"pivot": [3.2, 11.75, -5.01],
"cubes": [
{"origin": [2.2, 11.25, -5.01], "size": [2, 1, 0], "uv": [6, 16]}
]
},
{
"name": "eye_happy_left",
"parent": "eye_left",
"pivot": [3.2, 12, -5.01],
"cubes": [
{"origin": [1.7, 11, -5.01], "size": [3, 1, 0], "uv": [12, 16]},
{"origin": [2.7, 11.5, -5.02], "size": [1, 1, 0], "uv": [10, 16]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-3, 7, -4.5],
"pivot": [-3.2, 7.75, -5.01]
},
{
"name": "eye_right_open",
"parent": "eye_right",
"pivot": [-3.2, 7.75, -5.01],
"cubes": [
{"origin": [-3.5, 6, -4.5], "size": [1, 2, 0], "uv": [0, 12]}
{"origin": [-3.7, 6.75, -5.01], "size": [1, 1, 0], "uv": [2, 17], "mirror": true}
]
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [1.5, 6, -4.5],
"name": "eye_right_open2",
"parent": "eye_right_open",
"pivot": [-3.2, 8.25, -5.02],
"cubes": [
{"origin": [2.5, 6.5, -4.51], "size": [1, 1, 0], "uv": [42, 48]}
{"origin": [-3.7, 7.75, -5.01], "size": [1, 1, 0], "uv": [4, 17], "mirror": true}
]
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [4.5, 6, -4.5],
"name": "eye_closed_right",
"parent": "eye_right",
"pivot": [-3.2, 11.75, -5.01],
"cubes": [
{"origin": [-3.5, 6.5, -4.51], "size": [1, 1, 0], "uv": [42, 49], "mirror": true}
{"origin": [-4.2, 11.25, -5.01], "size": [2, 1, 0], "uv": [6, 17], "mirror": true}
]
},
{
"name": "eye_happy_right",
"parent": "eye_right",
"pivot": [-3.2, 12, -5.01],
"cubes": [
{"origin": [-4.7, 11, -5.01], "size": [3, 1, 0], "uv": [12, 17], "mirror": true},
{"origin": [-3.7, 11.5, -5.02], "size": [1, 1, 0], "uv": [10, 17], "mirror": true}
]
},
{
"name": "flame",
"parent": "head",
"pivot": [0, 4.5, 0],
"cubes": [
{"origin": [-2.5, 4.5, 0], "size": [5, 7, 0], "pivot": [0, 8, 0], "rotation": [0, 45, 0], "uv": [58, 9]},
{"origin": [0, 4.5, -2.5], "size": [0, 7, 5], "pivot": [0, 8, 0], "rotation": [0, 45, 0], "uv": [58, -3]}
]
},
{
"name": "brim",
"parent": "head",
"pivot": [0, 9.5, 0],
"pivot": [0, 11.5, 0],
"cubes": [
{"origin": [-7, 9.5, -7], "size": [14, 2, 14], "uv": [0, 0]},
{"origin": [-5, 11.5, -5], "size": [10, 2, 10], "uv": [0, 16]},
{"origin": [-1, 13.5, -1], "size": [2, 4, 2], "uv": [0, 16]}
]
},
{
"name": "arm_left",
"parent": "swing",
"pivot": [2.125, 2.75, 0],
"cubes": [
{"origin": [1.125, 2.75, -0.5], "size": [3, 0, 1], "uv": [26, 34]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [4.125, 2.75, 0],
"cubes": [
{"origin": [4.125, 2.75, -0.5], "size": [4, 0, 1], "uv": [0, 30]}
]
},
{
"name": "arm_left3",
"parent": "arm_left2",
"pivot": [8.125, 2.75, 0],
"cubes": [
{"origin": [8.125, 2.75, -0.5], "size": [4, 0, 1], "uv": [29, 25]}
]
},
{
"name": "arm_left4",
"parent": "arm_left3",
"pivot": [12.125, 2.75, 0],
"cubes": [
{"origin": [12.125, 2.75, -1], "size": [3, 0, 2], "uv": [28, 21]}
]
},
{
"name": "arm_left5",
"parent": "arm_left4",
"pivot": [15.125, 2.75, 0],
"cubes": [
{"origin": [15.125, 2.75, -1], "size": [3, 0, 2], "uv": [0, 28]}
]
},
{
"name": "arm_left6",
"parent": "arm_left5",
"pivot": [18.125, 2.75, 0],
"cubes": [
{"origin": [18.125, 2.75, -1], "size": [3, 0, 2], "uv": [0, 24]}
]
},
{
"name": "arm_right",
"parent": "swing",
"pivot": [-2.125, 2.75, 0],
"cubes": [
{"origin": [-4.125, 2.75, -0.5], "size": [3, 0, 1], "uv": [0, 34]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-4.125, 2.75, 0],
"cubes": [
{"origin": [-8.125, 2.75, -0.5], "size": [4, 0, 1], "uv": [29, 24]}
]
},
{
"name": "arm_right3",
"parent": "arm_right2",
"pivot": [-8.125, 2.75, 0],
"cubes": [
{"origin": [-12.125, 2.75, -0.5], "size": [4, 0, 1], "uv": [29, 23]}
]
},
{
"name": "arm_right4",
"parent": "arm_right3",
"pivot": [-12.125, 2.75, 0],
"cubes": [
{"origin": [-15.125, 2.75, -1], "size": [3, 0, 2], "uv": [0, 22]}
]
},
{
"name": "arm_right5",
"parent": "arm_right4",
"pivot": [-15.125, 2.75, 0],
"cubes": [
{"origin": [-18.125, 2.75, -1], "size": [3, 0, 2], "uv": [6, 12]}
]
},
{
"name": "arm_right6",
"parent": "arm_right5",
"pivot": [-18.125, 2.75, 0],
"cubes": [
{"origin": [-21.125, 2.75, -1], "size": [3, 0, 2], "uv": [0, 12]}
{"origin": [-9, 10.5, -9], "size": [18, 2, 18], "uv": [0, 0]},
{"origin": [-6.75, 12, -7], "size": [14, 2, 14], "uv": [54, 2]},
{"origin": [-4, 13.5, -4], "size": [8, 2, 8], "uv": [96, 6]},
{"origin": [-1, 15.5, -1], "size": [2, 5, 2], "uv": [96, 7]}
]
}
]
@@ -5,10 +5,10 @@
"description": {
"identifier": "geometry.chandelure",
"texture_width": 128,
"texture_height": 64,
"visible_bounds_width": 6,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
"texture_height": 128,
"visible_bounds_width": 8,
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
},
"bones": [
{
@@ -18,283 +18,548 @@
{
"name": "body",
"parent": "chandelure",
"pivot": [0, 0, 0]
"pivot": [0, 4, 0]
},
{
"name": "swing",
"parent": "body",
"pivot": [0, 41, 0]
"pivot": [0, 52, 0],
"cubes": [
{"origin": [-1, 0, -1], "size": [2, 3, 2], "inflate": 0.1, "uv": [40, 43]},
{"origin": [-2, 2.5, -2], "size": [4, 3, 4], "uv": [42, 28]},
{"origin": [-5, 5.51, -5], "size": [10, 2, 10], "uv": [2, 22]}
]
},
{
"name": "head",
"name": "arms",
"parent": "swing",
"pivot": [0, 5, 0],
"cubes": [
{"origin": [-6.5, 5, -6.4], "size": [13, 9, 13], "uv": [0, 0]},
{"origin": [-6.5, 5, -6.4], "size": [13, 0, 13], "inflate": 0.001, "uv": [51, 18]},
{"origin": [-6.5, 14, -6.4], "size": [13, 0, 13], "uv": [51, 31]},
{"origin": [-6.5, 5, -6.4], "size": [13, 9, 0], "uv": [63, 0]},
{"origin": [-6.5, 5, 6.6], "size": [13, 9, 0], "uv": [89, 0]},
{"origin": [-6.5, 5, -6.4], "size": [0, 9, 13], "uv": [63, -4]},
{"origin": [6.5, 5, -6.4], "size": [0, 9, 13], "uv": [89, -4]},
{"origin": [-1.5, 0, -1.5], "size": [3, 5, 3], "pivot": [0, 0, 0], "rotation": [0, -45, 0], "uv": [16, 36]}
]
},
{
"name": "eyes",
"parent": "head",
"pivot": [0.5, 9, -6]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [4.5, 9.5, -6],
"cubes": [
{"origin": [3, 8, -6.42], "size": [3, 3, 0], "uv": [26, 47]},
{"origin": [3, 8, -6.39], "size": [3, 3, 0], "uv": [26, 53]},
{"origin": [3.5, 8.5, -6.43], "size": [2, 2, 0], "uv": [12, 42]}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [0.5, 3.5, 0],
"cubes": [
{"origin": [-0.5, 2.5, -0.43], "size": [2, 2, 1], "inflate": 0.01, "uv": [51, 21]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-4.5, 9.5, -6],
"cubes": [
{"origin": [-6, 8, -6.42], "size": [3, 3, 0], "uv": [20, 47]},
{"origin": [-5.5, 8.5, -6.43], "size": [2, 2, 0], "uv": [12, 40]},
{"origin": [-6, 8, -6.39], "size": [3, 3, 0], "uv": [32, 53]}
]
},
{
"name": "eyelid_left2",
"parent": "eye_right",
"pivot": [-0.5, 3.5, 0],
"cubes": [
{"origin": [-1.5, 2.5, -0.43], "size": [2, 2, 1], "inflate": 0.01, "uv": [52, 18]}
]
},
{
"name": "brim",
"parent": "head",
"pivot": [0, 14, 0],
"cubes": [
{"origin": [-4, 14, -3], "size": [8, 3, 0], "pivot": [0, 14.5, -3], "rotation": [20, 0, 0], "uv": [40, 25]},
{"origin": [-3, 14, -4], "size": [0, 3, 8], "pivot": [-3, 14.5, 0], "rotation": [0, 0, -20], "uv": [16, 14]},
{"origin": [-4, 14, 3], "size": [8, 3, 0], "pivot": [0, 14.5, 3], "rotation": [-20, 0, 0], "uv": [39, 10]},
{"origin": [3, 14, -4], "size": [0, 3, 8], "pivot": [3, 14.5, 0], "rotation": [0, 0, 20], "uv": [0, 14]},
{"origin": [-3, 14.16, -3], "size": [6, 0, 6], "inflate": -0.15, "uv": [84, 18]}
]
},
{
"name": "flame_middle",
"parent": "head",
"pivot": [0, 14, 0],
"cubes": [
{"origin": [-3, 14, 0], "size": [6, 7, 0], "uv": [28, 36]},
{"origin": [0, 14, -3], "size": [0, 7, 6], "uv": [12, 19]}
]
},
{
"name": "flame_middle2",
"parent": "flame_middle",
"pivot": [0, 21, 0],
"cubes": [
{"origin": [-3, 21, 0], "size": [6, 7, 0], "uv": [39, 3]},
{"origin": [0, 21, -3], "size": [0, 7, 6], "uv": [0, 19]}
]
},
{
"name": "flame_middle3",
"parent": "flame_middle2",
"pivot": [0, 28, 0],
"cubes": [
{"origin": [-3, 28, 0], "size": [6, 7, 0], "uv": [0, 40]},
{"origin": [0, 28, -3], "size": [0, 7, 6], "uv": [0, 0]}
]
},
{
"name": "flame_inner",
"parent": "head",
"pivot": [0, 5, 0],
"cubes": [
{"origin": [-5, 5, 0], "size": [10, 9, 0], "uv": [100, 27]},
{"origin": [0, 5, -5], "size": [0, 9, 10], "uv": [100, 26]}
]
"pivot": [0, 4.25, 0]
},
{
"name": "arm_left",
"parent": "head",
"pivot": [2.125, 3, 0],
"parent": "arms",
"pivot": [2, 4.25, 0],
"cubes": [
{"origin": [1.125, 2, 0], "size": [6, 2, 0], "inflate": 0.01, "uv": [14, 54]}
{"origin": [1.5, 3.75, -0.5], "size": [9, 1, 1], "uv": [0, 34]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [7.125, 2, 0],
"pivot": [9.5, 4.25, 0],
"cubes": [
{"origin": [7.125, 2, 0], "size": [6, 2, 0], "uv": [40, 34]}
{"origin": [9, 3.25, -1], "size": [9, 2, 2], "inflate": -0.15, "uv": [20, 34]}
]
},
{
"name": "arm_left3",
"parent": "arm_left2",
"pivot": [13.125, 2, 0],
"pivot": [17.5, 4.25, 0],
"cubes": [
{"origin": [13.125, 2, 0], "size": [6, 2, 0], "inflate": 0.01, "uv": [0, 0]}
{"origin": [17, 3.25, -1], "size": [8, 2, 2], "uv": [0, 38]}
]
},
{
"name": "candle_front_left",
"parent": "arm_left3",
"pivot": [19, 4.25, -1],
"cubes": [
{"origin": [18.5, 4.25, -1.5], "size": [4, 0, 1], "uv": [57, 44]}
]
},
{
"name": "candle_front_left2",
"parent": "candle_front_left",
"pivot": [22.5, 4.25, -1],
"cubes": [
{"origin": [22, 4.25, -1.5], "size": [4, 0, 1], "inflate": 0.005, "uv": [76, 28]}
]
},
{
"name": "candle_front_left3",
"parent": "candle_front_left2",
"pivot": [26, 4.25, -1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [25.5, 4.25, -1.5], "size": [4, 0, 1], "inflate": 0.01, "uv": [-1, 62]}
]
},
{
"name": "candle_front_left4",
"parent": "candle_front_left3",
"pivot": [29.5, 4.25, -1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [29, 1.75, -3.5], "size": [6, 5, 5], "uv": [0, 42]}
]
},
{
"name": "flame_front_left",
"parent": "candle_front_left4",
"pivot": [34.5, 4.75, -1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [34, 2.25, -3], "size": [5, 4, 4], "uv": [44, 44]}
]
},
{
"name": "flame_front_left2",
"parent": "flame_front_left",
"pivot": [39, 4.25, -1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [38.5, 2.75, -2.5], "size": [4, 3, 3], "inflate": -0.1, "uv": [77, 39]}
]
},
{
"name": "flame_front_left3",
"parent": "flame_front_left2",
"pivot": [42.5, 4.25, -1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [42, 3.25, -1], "size": [4, 2, 0], "uv": [17, 43]}
]
},
{
"name": "candle_back_left",
"parent": "arm_left3",
"pivot": [19, 4.25, 1],
"cubes": [
{"origin": [18.5, 4.25, 0.5], "size": [4, 0, 1], "uv": [57, 46]}
]
},
{
"name": "candle_back_left2",
"parent": "candle_back_left",
"pivot": [22.5, 4.25, 1],
"cubes": [
{"origin": [22, 4.25, 0.5], "size": [4, 0, 1], "inflate": 0.005, "uv": [79, 34]}
]
},
{
"name": "candle_back_left3",
"parent": "candle_back_left2",
"pivot": [26, 4.25, 1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [25.5, 4.25, 0.5], "size": [4, 0, 1], "inflate": 0.01, "uv": [7, 62]}
]
},
{
"name": "candle_back_left4",
"parent": "candle_back_left3",
"pivot": [29.5, 4.25, 1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [29, 1.75, -1.5], "size": [6, 5, 5], "uv": [22, 43]}
]
},
{
"name": "flame_back_left",
"parent": "candle_back_left4",
"pivot": [34.5, 4.75, 1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [34, 2.25, -1], "size": [5, 4, 4], "uv": [62, 44]}
]
},
{
"name": "flame_back_left2",
"parent": "flame_back_left",
"pivot": [39, 4.25, 1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [38.5, 2.75, -0.5], "size": [4, 3, 3], "inflate": -0.1, "uv": [93, 36]}
]
},
{
"name": "flame_back_left3",
"parent": "flame_back_left2",
"pivot": [42.5, 4.25, 1],
"rotation": [0, 0, -0.00001],
"cubes": [
{"origin": [42, 3.25, 1], "size": [4, 2, 0], "uv": [17, 53]}
]
},
{
"name": "arm_left4",
"parent": "arm_left3",
"pivot": [19.125, 2, 0],
"pivot": [25, 4.25, 0],
"cubes": [
{"origin": [19.125, 2, 0], "size": [8, 8, 0], "uv": [0, 32]}
{"origin": [24, 3.25, -1], "size": [8, 2, 2], "inflate": 0.1, "uv": [42, 35]}
]
},
{
"name": "candleholder_front_left",
"name": "arm_left5",
"parent": "arm_left4",
"pivot": [19.125, 2, 0],
"pivot": [32, 4.25, 0],
"cubes": [
{"origin": [19.125, 2, -2], "size": [4, 0, 2], "uv": [10, 46]}
{"origin": [31, 3.25, -1], "size": [7, 2, 2], "inflate": 0.05, "uv": [40, 39]}
]
},
{
"name": "candleholder_front_left2",
"parent": "candleholder_front_left",
"pivot": [23.125, 2, -2],
"name": "arm_left6",
"parent": "arm_left5",
"pivot": [38, 4.25, 0],
"cubes": [
{"origin": [23.125, 2, -2], "size": [2, 0, 2], "uv": [30, 45]},
{"origin": [25.125, 0.5, -2.5], "size": [2, 3, 3], "uv": [49, 35]}
{"origin": [37, 3.25, -1], "size": [7, 2, 2], "uv": [58, 40]}
]
},
{
"name": "flame_front_left",
"parent": "candleholder_front_left2",
"pivot": [27.125, 2, -1],
"name": "arm_left7",
"parent": "arm_left6",
"pivot": [44, 4.25, 0],
"cubes": [
{"origin": [26.625, 2, -2.5], "size": [7, 0, 3], "uv": [36, 0]},
{"origin": [26.625, 0.5, -1], "size": [7, 3, 0], "uv": [40, 31]}
]
},
{
"name": "candleholder_back_left",
"parent": "arm_left4",
"pivot": [19.125, 2, 0],
"cubes": [
{"origin": [19.125, 2, 0], "size": [4, 0, 2], "uv": [22, 45]}
]
},
{
"name": "candleholder_back_left2",
"parent": "candleholder_back_left",
"pivot": [23.125, 2, 2],
"cubes": [
{"origin": [23.125, 2, 0], "size": [2, 0, 2], "uv": [38, 44]},
{"origin": [25.125, 0.5, -0.5], "size": [2, 3, 3], "uv": [54, 25]}
]
},
{
"name": "flame_back_left",
"parent": "candleholder_back_left2",
"pivot": [27.125, 2, 1],
"cubes": [
{"origin": [26.625, 2, -0.5], "size": [7, 0, 3], "uv": [-3, 50]},
{"origin": [26.625, 0.5, 1], "size": [7, 3, 0], "uv": [40, 28]}
{"origin": [43.5, 3.75, -0.5], "size": [6, 1, 1], "uv": [32, 28]}
]
},
{
"name": "arm_right",
"parent": "head",
"pivot": [-2.125, 3, 0],
"parent": "arms",
"pivot": [-2, 4.25, 0],
"cubes": [
{"origin": [-7.125, 2, 0], "size": [6, 2, 0], "inflate": 0.01, "uv": [14, 51]}
{"origin": [-10.5, 3.75, -0.5], "size": [9, 1, 1], "uv": [0, 36], "mirror": true}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-7.125, 2, 0],
"pivot": [-9.5, 4.25, 0],
"cubes": [
{"origin": [-13.125, 2, 0], "size": [6, 2, 0], "uv": [40, 36]}
{"origin": [-18, 3.25, -1], "size": [9, 2, 2], "inflate": -0.15, "uv": [54, 28], "mirror": true}
]
},
{
"name": "arm_right3",
"parent": "arm_right2",
"pivot": [-13.125, 2, 0],
"pivot": [-17.5, 4.25, 0],
"cubes": [
{"origin": [-19.125, 2, 0], "size": [6, 2, 0], "inflate": 0.01, "uv": [0, 3]}
{"origin": [-25, 3.25, -1], "size": [8, 2, 2], "uv": [20, 38], "mirror": true}
]
},
{
"name": "candle_front_right",
"parent": "arm_right3",
"pivot": [-19, 4.25, -1],
"cubes": [
{"origin": [-22.5, 4.25, -1.5], "size": [4, 0, 1], "uv": [57, 45], "mirror": true}
]
},
{
"name": "candle_front_right2",
"parent": "candle_front_right",
"pivot": [-22.5, 4.25, -1],
"cubes": [
{"origin": [-26, 4.25, -1.5], "size": [4, 0, 1], "inflate": 0.005, "uv": [76, 29], "mirror": true}
]
},
{
"name": "candle_front_right3",
"parent": "candle_front_right2",
"pivot": [-26, 4.25, -1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-29.5, 4.25, -1.5], "size": [4, 0, 1], "inflate": 0.01, "uv": [-1, 63], "mirror": true}
]
},
{
"name": "candle_front_right4",
"parent": "candle_front_right3",
"pivot": [-29.5, 4.25, -1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-35, 1.75, -3.5], "size": [6, 5, 5], "uv": [0, 52], "mirror": true}
]
},
{
"name": "flame_front_right",
"parent": "candle_front_right4",
"pivot": [-34.5, 4.75, -1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-39, 2.25, -3], "size": [5, 4, 4], "uv": [76, 64], "mirror": true}
]
},
{
"name": "flame_front_right2",
"parent": "flame_front_right",
"pivot": [-39, 4.25, -1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-42.5, 2.75, -2.5], "size": [4, 3, 3], "inflate": -0.1, "uv": [80, 45], "mirror": true}
]
},
{
"name": "flame_front_right3",
"parent": "flame_front_right2",
"pivot": [-42.5, 4.25, -1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-46, 3.25, -1], "size": [4, 2, 0], "uv": [17, 45], "mirror": true}
]
},
{
"name": "candle_back_right",
"parent": "arm_right3",
"pivot": [-19, 4.25, 1],
"cubes": [
{"origin": [-22.5, 4.25, 0.5], "size": [4, 0, 1], "uv": [57, 47], "mirror": true}
]
},
{
"name": "candle_back_right2",
"parent": "candle_back_right",
"pivot": [-22.5, 4.25, 1],
"cubes": [
{"origin": [-26, 4.25, 0.5], "size": [4, 0, 1], "inflate": 0.005, "uv": [79, 35], "mirror": true}
]
},
{
"name": "candle_back_right3",
"parent": "candle_back_right2",
"pivot": [-26, 4.25, 1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-29.5, 4.25, 0.5], "size": [4, 0, 1], "inflate": 0.01, "uv": [7, 63], "mirror": true}
]
},
{
"name": "candle_back_right4",
"parent": "candle_back_right3",
"pivot": [-29.5, 4.25, 1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-35, 1.75, -1.5], "size": [6, 5, 5], "uv": [0, 81], "mirror": true}
]
},
{
"name": "flame_back_right",
"parent": "candle_back_right4",
"pivot": [-34.5, 4.75, 1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-39, 2.25, -1], "size": [5, 4, 4], "uv": [60, 56], "mirror": true}
]
},
{
"name": "flame_back_right2",
"parent": "flame_back_right",
"pivot": [-39, 4.25, 1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-42.5, 2.75, -0.5], "size": [4, 3, 3], "inflate": -0.1, "uv": [82, 28], "mirror": true}
]
},
{
"name": "flame_back_right3",
"parent": "flame_back_right2",
"pivot": [-42.5, 4.25, 1],
"rotation": [0, 0, 0.00001],
"cubes": [
{"origin": [-46, 3.25, 1], "size": [4, 2, 0], "uv": [17, 55], "mirror": true}
]
},
{
"name": "arm_right4",
"parent": "arm_right3",
"pivot": [-19.125, 2, 0],
"pivot": [-25, 4.25, 0],
"cubes": [
{"origin": [-27.125, 2, 0], "size": [8, 8, 0], "uv": [24, 25]}
{"origin": [-32, 3.25, -1], "size": [8, 2, 2], "inflate": 0.1, "uv": [60, 32], "mirror": true}
]
},
{
"name": "candleholder_front_right",
"name": "arm_right5",
"parent": "arm_right4",
"pivot": [-19.125, 2, 0],
"pivot": [-32, 4.25, 0],
"cubes": [
{"origin": [-23.125, 2, -2], "size": [4, 0, 2], "uv": [38, 42]}
{"origin": [-38, 3.25, -1], "size": [7, 2, 2], "inflate": 0.05, "uv": [62, 36], "mirror": true}
]
},
{
"name": "candleholder_front_right2",
"parent": "candleholder_front_right",
"pivot": [-23.125, 2, -2],
"name": "arm_right6",
"parent": "arm_right5",
"pivot": [-38, 4.25, 0],
"cubes": [
{"origin": [-25.125, 2, -2], "size": [2, 0, 2], "uv": [30, 22]},
{"origin": [-27.125, 0.5, -2.5], "size": [2, 3, 3], "uv": [52, 10]}
{"origin": [-44, 3.25, -1], "size": [7, 2, 2], "uv": [60, 52], "mirror": true}
]
},
{
"name": "flame_front_right",
"parent": "candleholder_front_right2",
"pivot": [-27.125, 2, -1],
"name": "arm_right7",
"parent": "arm_right6",
"pivot": [-44, 4.25, 0],
"cubes": [
{"origin": [-33.625, 2, -2.5], "size": [7, 0, 3], "uv": [13, 33]},
{"origin": [-33.625, 0.5, -1], "size": [7, 3, 0], "uv": [36, 46]}
{"origin": [-49.5, 3.75, -0.5], "size": [6, 1, 1], "uv": [32, 30], "mirror": true}
]
},
{
"name": "candleholder_back_right",
"parent": "arm_right4",
"pivot": [-19.125, 2, 0],
"name": "head",
"parent": "swing",
"pivot": [0, 7.5, 0],
"cubes": [
{"origin": [-23.125, 2, 0], "size": [4, 0, 2], "uv": [38, 40]}
{"origin": [-8.5, 7.5, -8.5], "size": [17, 11, 17], "inflate": -0.01, "uv": [8, 53]},
{"origin": [-8.5, 7.5, -8.5], "size": [17, 11, 0], "uv": [0, 11]},
{"origin": [-8.5, 7.5, 8.5], "size": [17, 11, 0], "uv": [0, 0]},
{"origin": [-8.5, 18.5, -8.5], "size": [17, 0, 17], "uv": [17, 0]},
{"origin": [-8.5, 7.5, -8.5], "size": [17, 0, 17], "uv": [51, 0]},
{"origin": [8.5, 7.5, -8.5], "size": [0, 11, 17], "uv": [34, 0]},
{"origin": [-8.5, 7.5, -8.5], "size": [0, 11, 17], "uv": [68, 0], "mirror": true}
]
},
{
"name": "candleholder_back_right2",
"parent": "candleholder_back_right",
"pivot": [-23.125, 2, 2],
"name": "eyes",
"parent": "head",
"pivot": [0, 13, -8.51]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [6, 13, -8.51]
},
{
"name": "eye_open_left",
"parent": "eye_left",
"pivot": [6, 13, -8.51],
"cubes": [
{"origin": [-25.125, 2, 0], "size": [2, 0, 2], "uv": [38, 38]},
{"origin": [-27.125, 0.5, -0.5], "size": [2, 3, 3], "uv": [29, 47]}
{"origin": [5, 12, -8.51], "size": [2, 2, 0], "uv": [0, 64]}
]
},
{
"name": "flame_back_right",
"parent": "candleholder_back_right2",
"pivot": [-27.125, 2, 1],
"name": "eye_expression_left",
"parent": "eye_open_left",
"pivot": [6, 14, -8.42],
"cubes": [
{"origin": [-33.625, 2, -0.5], "size": [7, 0, 3], "uv": [-3, 47]},
{"origin": [-33.625, 0.5, 1], "size": [7, 3, 0], "uv": [48, 41]}
{"origin": [5.5, 13.5, -8.42], "size": [1, 1, 0], "uv": [0, 69]}
]
},
{
"name": "eye_closed_left",
"parent": "eye_left",
"pivot": [6, 12.5, -8.41],
"cubes": [
{"origin": [5, 12, -8.41], "size": [2, 1, 0], "uv": [0, 66]}
]
},
{
"name": "eye_happy_left",
"parent": "eye_left",
"pivot": [6, 12.75, -8.41],
"cubes": [
{"origin": [4.499, 12.25, -8.41], "size": [3, 1, 0], "uv": [0, 67]},
{"origin": [5.5, 12.75, -8.41], "size": [1, 1, 0], "uv": [2, 69]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-6, 13, -8.51]
},
{
"name": "eye_open_right",
"parent": "eye_right",
"pivot": [-6, 13, -8.51],
"cubes": [
{"origin": [-7, 12, -8.51], "size": [2, 2, 0], "uv": [4, 64], "mirror": true}
]
},
{
"name": "eye_expression_right",
"parent": "eye_open_right",
"pivot": [-6, 14, -8.42],
"cubes": [
{"origin": [-6.5, 13.5, -8.42], "size": [1, 1, 0], "uv": [0, 70], "mirror": true}
]
},
{
"name": "eye_closed_right",
"parent": "eye_right",
"pivot": [-6, 12.5, -8.41],
"cubes": [
{"origin": [-7, 12, -8.41], "size": [2, 1, 0], "uv": [4, 66], "mirror": true}
]
},
{
"name": "eye_happy_right",
"parent": "eye_right",
"pivot": [-6, 12.75, -8.41],
"cubes": [
{"origin": [-7.499, 12.25, -8.41], "size": [3, 1, 0], "uv": [0, 68], "mirror": true},
{"origin": [-6.5, 12.75, -8.41], "size": [1, 1, 0], "uv": [2, 70], "mirror": true}
]
},
{
"name": "flame_inner",
"parent": "head",
"pivot": [0, 7.5, -0.1],
"cubes": [
{"origin": [-3, 7, -3.1], "size": [6, 3, 6], "uv": [102, 2]}
]
},
{
"name": "flame_inner2",
"parent": "flame_inner",
"pivot": [0, 8.75, -0.1],
"cubes": [
{"origin": [-4, 8.75, -4.1], "size": [8, 8, 8], "uv": [96, 20]}
]
},
{
"name": "flame_inner3",
"parent": "flame_inner2",
"pivot": [0, 16.75, -0.1],
"cubes": [
{"origin": [-3, 15.5, -3.1], "size": [6, 3, 6], "uv": [102, 11]}
]
},
{
"name": "brim",
"parent": "head",
"pivot": [0, 19, -0.1],
"cubes": [
{"origin": [-3.5, 18.5, -3.6], "size": [7, 1, 7], "inflate": 0.01, "uv": [100, 36]},
{"origin": [-3.5, 18.76, -3.35], "size": [7, 3, 0], "pivot": [0, 18.75, -3.35], "rotation": [25, 0, 0], "uv": [106, 44]},
{"origin": [-3.5, 18.76, 3.15], "size": [7, 3, 0], "pivot": [0, 18.75, 3.15], "rotation": [-25, 0, 0], "uv": [112, 47]},
{"origin": [3.25, 18.76, -3.6], "size": [0, 3, 7], "pivot": [3.25, 18.75, -0.1], "rotation": [0, 0, 25], "uv": [80, 29]},
{"origin": [-3.25, 18.76, -3.6], "size": [0, 3, 7], "pivot": [-3.25, 18.75, -0.1], "rotation": [0, 0, -25], "uv": [59, 57], "mirror": true}
]
},
{
"name": "flame_middle",
"parent": "brim",
"pivot": [0, 19, -0.1],
"cubes": [
{"origin": [-3, 19, -3.1], "size": [6, 8, 6], "uv": [104, 50]}
]
},
{
"name": "flame_middle2",
"parent": "flame_middle",
"pivot": [0, 26, -0.1],
"cubes": [
{"origin": [-2.5, 25.5, -2.6], "size": [5, 8, 5], "uv": [78, 51]}
]
},
{
"name": "flame_middle3",
"parent": "flame_middle2",
"pivot": [0, 33, -0.1],
"cubes": [
{"origin": [-2, 32, -2.1], "size": [4, 7, 4], "uv": [94, 45]}
]
},
{
"name": "flame_middle4",
"parent": "flame_middle3",
"pivot": [0, 39, -0.1],
"cubes": [
{"origin": [-1.5, 38, -1.6], "size": [3, 7, 3], "uv": [0, 22]}
]
},
{
"name": "flame_middle5",
"parent": "flame_middle4",
"pivot": [0, 45, -0.1],
"cubes": [
{"origin": [-1, 44, -0.1], "size": [2, 6, 0], "uv": [120, 11]}
]
}
]
@@ -53,7 +53,6 @@
"isTouchingWater": true,
"isUnderWater": false,
"animations": [
"q.look('body')",
"q.bedrock('staryu', 'surfacewater_swim')"
]
},
@@ -71,7 +70,6 @@
"isUnderWater": true,
"animations": [
"q.pitch_tilt('body', 1)",
"q.look('body')",
"q.bedrock('staryu', 'water_swim')"
]
}
@@ -92,7 +92,6 @@
"isTouchingWater": true,
"isUnderWater": false,
"animations": [
"q.look('body')",
"q.bedrock('starmie', 'surfacewater_swim')"
]
},
@@ -114,7 +113,6 @@
"isUnderWater": true,
"animations": [
"q.pitch_tilt('body', 1)",
"q.look('body')",
"q.bedrock('starmie', 'water_swim')"
]
}
@@ -21,6 +21,7 @@
"poses": {
"jump": {
"poseTypes": ["STAND", "WALK"],
"isBattle": false,
"condition": "q.in_air",
"animations": [
"q.look('head')",
@@ -38,7 +39,6 @@
},
"running": {
"poseTypes": ["WALK", "FLOAT", "SWIM"],
"isBattle": false,
"condition": "!q.in_air && q.is_sprinting",
"animations": [
"q.look('head')",
@@ -65,7 +65,6 @@
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"condition": "!q.in_air",
"animations": [
"q.look('head')",
@@ -56,7 +56,6 @@
},
"running": {
"poseTypes": ["WALK"],
"isBattle": false,
"isTouchingWater": false,
"condition": "!q.in_air && q.is_sprinting",
"animations": [
@@ -85,7 +84,6 @@
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"isTouchingWater": false,
"condition": "!q.in_air",
"animations": [
@@ -99,7 +97,6 @@
"quirks": ["q.bedrock_quirk('tauros_paldean_aqua', 'blink')"]
},
"surface-swimming": {
"isBattle": false,
"isTouchingWater": true,
"poseTypes": ["WALK", "SWIM"],
"animations": [
@@ -112,7 +109,6 @@
"quirks": ["q.bedrock_quirk('tauros_paldean_aqua', 'blink')"]
},
"surface-floating": {
"isBattle": false,
"isTouchingWater": true,
"poseTypes": ["STAND", "FLOAT"],
"animations": [
@@ -38,7 +38,6 @@
},
"running": {
"poseTypes": ["WALK", "FLOAT", "SWIM"],
"isBattle": false,
"condition": "!q.in_air && q.is_sprinting",
"animations": [
"q.look('head')",
@@ -65,7 +64,6 @@
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"condition": "!q.in_air",
"animations": [
"q.look('head')",
@@ -36,7 +36,7 @@
"q.look('body', 0.5, 0.5)",
"q.bedrock('crobat', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('crobat', 'blink')","q.bedrock_quirk('crobat', 'fang_quirk')"],
"quirks": ["q.bedrock_quirk('crobat', 'blink')"],
"transformTicks": 10
},
"walk": {
@@ -52,7 +52,6 @@
"isUnderWater": true,
"animations": [
"q.pitch_tilt('body')",
"q.look('head')",
"q.bedrock('corsola', 'water_swim')"
],
"quirks": ["q.bedrock_quirk('corsola', 'blink')"]
@@ -78,7 +77,6 @@
"isUnderWater": false,
"animations": [
"q.pitch_tilt('body')",
"q.look('head')",
"q.bedrock('corsola', 'surfacewater_swim')"
],
"quirks": ["q.bedrock_quirk('corsola', 'blink')"]
@@ -0,0 +1,51 @@
{
"portraitScale": 2.35,
"portraitTranslation": [-0.09, -0.55, 0],
"profileScale": 0.72,
"profileTranslation": [0, 0.73, 0],
"rootBone": "elgyem",
"animations": {
"cry": "q.bedrock_stateful('elgyem', 'cry')",
"recoil": "q.bedrock_stateful('elgyem', 'recoil')"
},
"poses": {
"battle-standing": {
"poseTypes": ["STAND"],
"isBattle": true,
"animations": ["q.look('head_ai')", "q.bedrock('elgyem', 'battle_idle')"],
"quirks": [
"q.bedrock_quirk('elgyem', 'blink')",
"q.bedrock_quirk('elgyem', 'lights_quirk1')",
"q.bedrock_quirk('elgyem', 'lights_quirk2')",
"q.bedrock_quirk('elgyem', 'lights_quirk3')"
]
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": ["q.look('head_ai')", "q.bedrock('elgyem', 'ground_idle')"],
"quirks": [
"q.bedrock_quirk('elgyem', 'blink')",
"q.bedrock_quirk('elgyem', 'look_quirk')",
"q.bedrock_quirk('elgyem', 'lights_quirk1')",
"q.bedrock_quirk('elgyem', 'lights_quirk2')",
"q.bedrock_quirk('elgyem', 'lights_quirk3')"
]
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"animations": ["q.look('head_ai')", "q.bedrock('elgyem', 'ground_walk')"],
"quirks": [
"q.bedrock_quirk('elgyem', 'blink')",
"q.bedrock_quirk('elgyem', 'look_quirk')",
"q.bedrock_quirk('elgyem', 'lights_quirk1')",
"q.bedrock_quirk('elgyem', 'lights_quirk2')",
"q.bedrock_quirk('elgyem', 'lights_quirk3')"
]
},
"sleep": {
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('elgyem', 'sleep')"]
}
}
}
@@ -0,0 +1,48 @@
{
"portraitScale": 2.32,
"portraitTranslation": [-0.52, 0.04, 0],
"profileScale": 0.71,
"profileTranslation": [0, 0.7, 0],
"rootBone": "beheeyem",
"animations": {
"cry": "q.bedrock_stateful('beheeyem', 'cry')"
},
"poses": {
"battle-standing": {
"poseTypes": ["STAND"],
"isBattle": true,
"animations": ["q.look('head_ai')", "q.bedrock('beheeyem', 'battle_idle')"],
"quirks": [
"q.bedrock_quirk('beheeyem', 'blink')",
"q.bedrock_quirk('beheeyem', 'lights_quirk1')",
"q.bedrock_quirk('beheeyem', 'lights_quirk2')",
"q.bedrock_quirk('beheeyem', 'lights_quirk3')"
]
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": ["q.look('head_ai')", "q.bedrock('beheeyem', 'ground_idle')"],
"quirks": [
"q.bedrock_quirk('beheeyem', 'blink')",
"q.bedrock_quirk('beheeyem', 'lights_quirk1')",
"q.bedrock_quirk('beheeyem', 'lights_quirk2')",
"q.bedrock_quirk('beheeyem', 'lights_quirk3')"
]
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"animations": ["q.look('head_ai')", "q.bedrock('beheeyem', 'ground_walk')"],
"quirks": [
"q.bedrock_quirk('beheeyem', 'blink')",
"q.bedrock_quirk('beheeyem', 'lights_quirk1')",
"q.bedrock_quirk('beheeyem', 'lights_quirk2')",
"q.bedrock_quirk('beheeyem', 'lights_quirk3')"
]
},
"sleep": {
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('beheeyem', 'sleep')"]
}
}
}
@@ -0,0 +1,87 @@
{
"portraitScale": 1.9,
"portraitTranslation": [-0.04,-1.19,0],
"profileScale": 0.8,
"profileTranslation": [0,0.49,0],
"rootBone": "litwick",
"poses": {
"standing": {
"poseTypes": [
"STAND",
"FLOAT",
"NONE",
"PROFILE",
"PORTRAIT"
],
"isBattle": false,
"animations": [
"q.look('head', 1, 1, 0, 0, 7, -7)",
"q.look('head2', 1, 1, 7, -7, 0, 0)",
"q.bedrock('litwick', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('litwick', 'blink')"
]
},
"walk": {
"poseTypes": [
"WALK",
"SWIM"
],
"animations": [
"q.look('head', 1, 1, 0, 0, 7, -7)",
"q.look('head2', 1, 1, 7, -7, 0, 0)",
"q.bedrock('litwick', 'ground_walk')"
],
"quirks": [
"q.bedrock_quirk('litwick', 'blink')"
]
},
"battle_idle": {
"poseTypes": ["STAND"],
"isBattle": true,
"animations": [
"q.look('head', 1, 1, 0, 0, 7, -7)",
"q.look('head2', 1, 1, 7, -7, 0, 0)",
"q.bedrock('litwick', 'battle_idle')"
],
"quirks": [
"q.bedrock_quirk('litwick', 'blink')"
]
},
"sleep": {
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('litwick', 'sleep')"]
},
"shoulder_left": {
"poseTypes": ["SHOULDER_LEFT"],
"animations": [
"q.look('head', 1, 1, 0, 0, 7, -7)",
"q.look('head2', 1, 1, 7, -7, 0, 0)",
"q.bedrock('litwick', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('litwick', 'blink')"],
"transformedParts": [
{
"part": "body",
"position": [1.5, 0, 0]
}
]
},
"shoulder_right": {
"poseTypes": ["SHOULDER_RIGHT"],
"animations": [
"q.look('head', 1, 1, 0, 0, 7, -7)",
"q.look('head2', 1, 1, 7, -7, 0, 0)",
"q.bedrock('litwick', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('litwick', 'blink')"],
"transformedParts": [
{
"part": "body",
"position": [-1.5, 0, 0]
}
]
}
}
}
@@ -0,0 +1,60 @@
{
"portraitScale": 1.65,
"portraitTranslation": [-0.1,0.15,0],
"profileScale": 0.77,
"profileTranslation": [0,0.52,0],
"rootBone": "lampent",
"poses": {
"sleep": {
"poseName": "sleep",
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('lampent', 'sleep')"]
},
"standing": {
"poseTypes": [
"STAND",
"NONE",
"PORTRAIT",
"PROFILE"
],
"isBattle": false,
"animations": [
"q.look('body')",
"q.bedrock('lampent', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('lampent', 'blink')"]
},
"walk": {
"poseTypes": ["WALK"],
"animations": ["q.bedrock('lampent', 'ground_walk')"],
"quirks": ["q.bedrock_quirk('lampent', 'blink')"]
},
"hover": {
"poseTypes": ["HOVER"],
"isBattle": false,
"animations": [
"q.pitch_tilt('body')",
"q.look('body')",
"q.bedrock('lampent', 'air_idle')"
],
"quirks": ["q.bedrock_quirk('lampent', 'blink')"]
},
"fly": {
"poseTypes": ["FLY"],
"animations": [
"q.pitch_tilt('body')",
"q.bedrock('lampent', 'air_fly')"
],
"quirks": ["q.bedrock_quirk('lampent', 'blink')"]
},
"battle_standing": {
"poseTypes": ["STAND", "HOVER"],
"isBattle": true,
"animations": [
"q.look('body')",
"q.bedrock('lampent', 'battle_idle')"
],
"quirks": ["q.bedrock_quirk('lampent', 'blink')"]
}
}
}
@@ -0,0 +1,60 @@
{
"portraitScale": 1.53,
"portraitTranslation": [-0.32,0.48,0],
"profileScale": 0.57,
"profileTranslation": [0,0.99,0],
"rootBone": "chandelure",
"poses": {
"standing": {
"isBattle": false,
"poseTypes": [
"STAND",
"NONE",
"PORTRAIT",
"PROFILE"
],
"animations": [
"q.look('body')",
"q.bedrock('chandelure', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('chandelure', 'blink')"]
},
"walk": {
"poseTypes": ["WALK"],
"animations": ["q.bedrock('chandelure', 'ground_walk')"],
"quirks": ["q.bedrock_quirk('chandelure', 'blink')"]
},
"hover": {
"poseTypes": ["HOVER"],
"isBattle": false,
"animations": [
"q.pitch_tilt('body')",
"q.look('body')",
"q.bedrock('chandelure', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('chandelure', 'blink')"]
},
"fly": {
"poseTypes": ["FLY"],
"animations": [
"q.pitch_tilt('body')",
"q.bedrock('chandelure', 'ground_walk')"
],
"quirks": ["q.bedrock_quirk('chandelure', 'blink')"]
},
"battle-standing": {
"poseTypes": ["STAND", "HOVER"],
"isBattle": true,
"animations": [
"q.look('body')",
"q.bedrock('chandelure', 'battle_idle')"
],
"quirks": ["q.bedrock_quirk('chandelure', 'blink')"]
},
"sleep": {
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('chandelure', 'sleep')"
]
}
}
}
@@ -26,16 +26,26 @@
"animations": ["q.look('head_ai')", "q.bedrock('hydreigon', 'potrait_pose')"],
"quirks": ["q.bedrock_quirk('hydreigon', 'blink')"]
},
"standing": {
"mount-standing": {
"poseTypes": ["STAND", "NONE", "PROFILE"],
"isBattle": false,
"condition": "q.is_ridden",
"animations": [
"q.look('head_ai')",
"q.bedrock('hydreigon', 'air_idle')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('hydreigon', 'ride_air_fly')"
}
"q.bedrock('hydreigon', 'ride_air_fly')"
],
"quirks": [
"q.bedrock_quirk('hydreigon', 'blink')"
]
},
"standing": {
"poseTypes": ["STAND", "NONE", "PROFILE"],
"isBattle": false,
"condition": "!q.is_ridden",
"animations": [
"q.look('head_ai')",
"q.bedrock('hydreigon', 'air_idle')"
],
"quirks": [
"q.bedrock_quirk('hydreigon', 'blink')",
@@ -55,17 +65,28 @@
],
"quirks": ["q.bedrock_quirk('hydreigon', 'blink')"]
},
"hover": {
"mount-hover": {
"poseTypes": ["HOVER", "NONE"],
"isBattle": false,
"condition": "q.is_ridden",
"animations": [
"q.pitch_tilt('body', 1)",
"q.look('head_ai')",
"q.bedrock('hydreigon', 'air_idle')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('hydreigon', 'ride_air_fly')"
}
"q.bedrock('hydreigon', 'ride_air_fly')"
],
"quirks": [
"q.bedrock_quirk('hydreigon', 'blink')"
]
},
"hover": {
"poseTypes": ["HOVER", "NONE"],
"isBattle": false,
"condition": "!q.is_ridden",
"animations": [
"q.pitch_tilt('body', 1)",
"q.look('head_ai')",
"q.bedrock('hydreigon', 'air_idle')"
],
"quirks": [
"q.bedrock_quirk('hydreigon', 'blink')",
@@ -9,16 +9,8 @@
"texture": "cobblemon:textures/pokemon/0605_elgyem/elgyem.png",
"layers": [
{
"name": "color",
"texture": {
"frames": [
"cobblemon:textures/pokemon/0605_elgyem/glow/hand_glow_green.png",
"cobblemon:textures/pokemon/0605_elgyem/glow/hand_glow_red.png",
"cobblemon:textures/pokemon/0605_elgyem/glow/hand_glow_yellow.png"
],
"fps": 5,
"loop": true
},
"name": "glow",
"texture": "cobblemon:textures/pokemon/0605_elgyem/elgyem_emissive.png",
"emissive": true
}
]
@@ -28,16 +20,8 @@
"texture": "cobblemon:textures/pokemon/0605_elgyem/elgyem_shiny.png",
"layers": [
{
"name": "color",
"texture": {
"frames": [
"cobblemon:textures/pokemon/0605_elgyem/glow/hand_shiny_blue.png",
"cobblemon:textures/pokemon/0605_elgyem/glow/hand_shiny_purple.png",
"cobblemon:textures/pokemon/0605_elgyem/glow/hand_shiny_yellow.png"
],
"fps": 5,
"loop": true
},
"name": "glow",
"texture": "cobblemon:textures/pokemon/0605_elgyem/elgyem_emissive_shiny.png",
"emissive": true
}
]
@@ -9,16 +9,8 @@
"texture": "cobblemon:textures/pokemon/0606_beheeyem/beheeyem.png",
"layers": [
{
"name": "color",
"texture": {
"frames": [
"cobblemon:textures/pokemon/0606_beheeyem/glow/hand_glow_yellow.png",
"cobblemon:textures/pokemon/0606_beheeyem/glow/hand_glow_red.png",
"cobblemon:textures/pokemon/0606_beheeyem/glow/hand_glow_green.png"
],
"fps": 5,
"loop": true
},
"name": "glow",
"texture": "cobblemon:textures/pokemon/0606_beheeyem/beheeyem_emissive.png",
"emissive": true
}
]
@@ -28,16 +20,8 @@
"texture": "cobblemon:textures/pokemon/0606_beheeyem/beheeyem_shiny.png",
"layers": [
{
"name": "shiny_color",
"texture": {
"frames": [
"cobblemon:textures/pokemon/0606_beheeyem/glow/hand_shiny_blue.png",
"cobblemon:textures/pokemon/0606_beheeyem/glow/hand_shiny_purple.png",
"cobblemon:textures/pokemon/0606_beheeyem/glow/hand_shiny_green.png"
],
"fps": 5,
"loop": true
},
"name": "glow",
"texture": "cobblemon:textures/pokemon/0606_beheeyem/beheeyem_emissive_shiny.png",
"emissive": true
}
]
@@ -9,9 +9,10 @@
"texture": "cobblemon:textures/pokemon/0607_litwick/litwick.png",
"layers": [
{
"name": "color",
"name": "emissive",
"texture": "cobblemon:textures/pokemon/0607_litwick/litwick_emissive.png",
"emissive": true
"emissive": true,
"translucent": true
}
]
},
@@ -20,9 +21,10 @@
"texture": "cobblemon:textures/pokemon/0607_litwick/litwick_shiny.png",
"layers": [
{
"name": "color",
"texture": "cobblemon:textures/pokemon/0607_litwick/litwick_shiny_emissive.png",
"emissive": true
"name": "emissive",
"texture": "cobblemon:textures/pokemon/0607_litwick/litwick_emissive_shiny.png",
"emissive": true,
"translucent": true
}
]
}
@@ -9,9 +9,10 @@
"texture": "cobblemon:textures/pokemon/0608_lampent/lampent.png",
"layers": [
{
"name": "color",
"name": "emissive",
"texture": "cobblemon:textures/pokemon/0608_lampent/lampent_emissive.png",
"emissive": true
"emissive": true,
"translucent": true
}
]
},
@@ -20,9 +21,10 @@
"texture": "cobblemon:textures/pokemon/0608_lampent/lampent_shiny.png",
"layers": [
{
"name": "color",
"texture": "cobblemon:textures/pokemon/0608_lampent/lampent_shiny_emissive.png",
"emissive": true
"name": "emissive",
"texture": "cobblemon:textures/pokemon/0608_lampent/lampent_emissive_shiny.png",
"emissive": true,
"translucent": true
}
]
}
@@ -9,13 +9,16 @@
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure.png",
"layers": [
{
"name": "color",
"name": "emissive",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_emissive.png",
"emissive": true
"emissive": true,
"translucent": true
},
{
"name": "trim",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_trim.png"
"name": "transparency",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_transparency.png",
"translucent": true,
"translucent_cull": true
}
]
},
@@ -24,13 +27,16 @@
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_shiny.png",
"layers": [
{
"name": "color",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_shiny_emissive.png",
"emissive": true
"name": "emissive",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_emissive_shiny.png",
"emissive": true,
"translucent": true
},
{
"name": "trim",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_trim.png"
"name": "transparency",
"texture": "cobblemon:textures/pokemon/0609_chandelure/chandelure_transparency_shiny.png",
"translucent": true,
"translucent_cull": true
}
]
}
@@ -6467,9 +6467,9 @@
"item.cobblemon.iron.tooltip": "Erhöht die EVs der Vert um 10",
"item.cobblemon.protein.tooltip": "Erhöht die EVs des Angriffs um 10",
"item.cobblemon.zinc.tooltip": "Erhöht die EVs der Sp. Ver. um 10",
"item.cobblemon.potion.tooltip": "Stellt 60 KP eines Pokémon wieder her",
"item.cobblemon.super_potion.tooltip": "Stellt 100 KP eines Pokémon wieder her",
"item.cobblemon.hyper_potion.tooltip": "Stellt 150 KP eines Pokémon wieder her",
"item.cobblemon.potion.tooltip": "Stellt 20 KP eines Pokémon wieder her",
"item.cobblemon.super_potion.tooltip": "Stellt 60 KP eines Pokémon wieder her",
"item.cobblemon.hyper_potion.tooltip": "Stellt 120 KP eines Pokémon wieder her",
"item.cobblemon.max_potion.tooltip": "Stellt sämtliche KP eines Pokémon wieder her",
"item.cobblemon.full_restore.tooltip": "Stellt sämtliche KP eines Pokémon wieder her und befreit es von sämtlichen Statusproblemen",
"item.cobblemon.health_feather.tooltip": "Erhöht die EVs der KP um 1",
@@ -6581,5 +6581,29 @@
"item.cobblemon.light_ball.tooltip": "Erhöht Pikachu´s Angriff und Spezial-Angriff",
"item.cobblemon.loaded_dice.tooltip": "Serienattacken treffen mindestens viermal",
"item.cobblemon.lucky_egg.tooltip": "Erhöht die im Kampf erhaltene EP für den Träger",
"item.cobblemon.metronome.tooltip": "Verstärkt eine Attacke, je öfter sie in Folge ausgeführt wird"
"item.cobblemon.metronome.tooltip": "Verstärkt eine Attacke, je öfter sie in Folge ausgeführt wird",
"item.cobblemon.red_card.tooltip_1": "Pokémon, die dem Träger Schaden zufügen, werden zum Auswechseln gezwungen",
"item.cobblemon.scroll_of_darkness": "Unlicht-Schriftrolle",
"item.cobblemon.punching_glove.tooltip": "Stärkt die Stärke der Punch-Attacken des Trägers und verhindert, dass diese Kontakt mit dem Ziel herstellen",
"item.cobblemon.razor_claw.tooltip_2": "Entwickelt Sniebel zu Snieboss oder Snibunna, wenn es tagsüber bzw. nachts beim Levelaufstieg getragen wird",
"item.cobblemon.ring_target.tooltip": "Die Typen-Immunitäten des Trägers werden aufgehoben",
"item.cobblemon.safety_goggles.tooltip": "Verleiht dem Träger Immunität gegenüber Puder- und Sporen-Attacken sowie Wetterschaden",
"item.cobblemon.hearty_grains": "Munterreis",
"item.cobblemon.bugwort": "Schutzblume",
"item.cobblemon.metal_alloy": "Legierungsmetall",
"item.cobblemon.scroll_of_waters": "Wasser-Schriftrolle",
"item.cobblemon.metal_alloy.tooltip": "Entwickelt Duraludon zu Briduradon",
"item.cobblemon.scroll_of_darkness.tooltip": "Entwickelt Dakuma zu Wulaosu im Fokussierten Stil",
"item.cobblemon.scroll_of_waters.tooltip": "Entwickelt Dakuma zu Wulaosu im Fließenden Stil",
"item.cobblemon.potato_mochi": "Kartoffel-Mochi",
"item.cobblemon.fried_rice": "Gebratener Reis",
"item.cobblemon.candied_apple": "Kandierter Apfel",
"item.cobblemon.protective_pads.tooltip": "Schützt den Träger vor Kontakt-Effekten des Ziels",
"item.cobblemon.quick_claw.tooltip": "Ermöglicht dem Träger gelegentlich, zuerst anzugreifen",
"item.cobblemon.razor_claw.tooltip_1": "Erhöht die Volltrefferquote der Attacken des Trägers",
"item.cobblemon.razor_fang.tooltip_1": "Verursacht der Träger Schaden, schreckt das Ziel eventuell zurück",
"item.cobblemon.razor_fang.tooltip_2": "Entwickelt Skorgla zu Skorgro, wenn es nachts beim Levelaufstieg getragen wird",
"item.cobblemon.rocky_helmet.tooltip": "Fügt einem Pokémon, das direkten Kontakt mit dem Träger herstellt, Schaden zu",
"item.cobblemon.room_service.tooltip_1": "Senkt die Initiative des Trägers, wenn Bizarroraum aktiv ist",
"item.cobblemon.scope_lens.tooltip": "Erhöht die Volltrefferquote des Trägers"
}
@@ -11,5 +11,63 @@
"cobblemon.ui.entity.behaviour_editor": "Behaviours",
"cobblemon.ui.entity.behaviour_editor.label": "Behaviours - %1$s",
"cobblemon.ui.entity.behaviour_editor.label.active": "Active Behaviours",
"cobblemon.ui.entity.behaviour_editor.label.inactive": "Inactive Behaviours"
"cobblemon.ui.entity.behaviour_editor.label.inactive": "Inactive Behaviours",
"cobblemon.ui.pokedex.info.form.squawkabilly-color-gray": "Grey",
"cobblemon.species.alcremie-rubycream.desc": "The moment it evolved, it took on a sweet and tart flavour. This is because of the way its cells spontaneously shifted during evolution.",
"advancements.cobblemon.craft_base_balls.description": "Craft all seven of the basic coloured Poké Balls",
"cobblemon.move.aurorabeam.desc": "The target is hit with a rainbow-coloured beam. This may also lower the target's Attack stat.",
"cobblemon.species.venusaur.desc": "There is a large flower on Venusaur's back. The flower is said to take on vivid colours if it gets plenty of nutrition and sunlight. The flower's aroma soothes the emotions of people.",
"cobblemon.species.charmeleon.desc": "Charmeleon mercilessly destroys its foes using its sharp claws. If it encounters a strong foe, it turns aggressive. In this excited state, the flame at the tip of its tail flares with a bluish white colour.",
"cobblemon.species.starmie.desc": "Starmie swims through water by spinning its star-shaped body as if it were a propeller on a ship. The core at the center of this Pokémon's body glows in seven colours.",
"cobblemon.species.hooh.desc": "Ho-Oh's feathers glow in seven colours depending on the angle at which they are struck by light. These feathers are said to bring happiness to the bearers. This Pokémon is said to live at the foot of a rainbow.",
"cobblemon.species.shellos.desc": "Its shape and colouration vary, depending on its habitat.",
"cobblemon.species.vivillon.desc": "The patterns on this Pokémon's wings depend on the climate and topography of its habitat. It scatters colourful scales.",
"cobblemon.species.roselia.desc": "On extremely rare occasions, a Roselia is said to appear with its flowers in unusual colours. The thorns on this Pokémon's head contain a vicious poison.",
"cobblemon.species.kecleon.desc": "Kecleon alters its body colouration to blend in with its surroundings, allowing it to sneak up on its prey unnoticed. Then it lashes out with its long, stretchy tongue to instantly ensnare the unsuspecting target.",
"cobblemon.species.munna.desc": "It eats the dreams of people and Pokémon. When it eats a pleasant dream, it expels pink-coloured mist.",
"cobblemon.species.musharna.desc": "The dream mist coming from its forehead changes into many different colours depending on the dream that was eaten.",
"cobblemon.species.basculin-bluestriped.desc": "These Pokémon form schools with others of the same colour. The greatest foe of a school of blue Basculin is a school of red Basculin.",
"cobblemon.species.xerneas.desc": "When the horns on its head shine in seven colours, it is said to be sharing everlasting life.",
"cobblemon.species.minior.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.species.minior-indigo.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.species.minior-violet.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.species.swinub.desc": "Swinub roots for food by rubbing its snout against the ground. Its favourite food is a mushroom that grows under the cover of dead grass. This Pokémon occasionally roots out hot springs.",
"cobblemon.species.fomantis.desc": "It loves the sunshine. When it basks in the sunlight regularly, it grows up with vivid colouration.",
"cobblemon.species.minior-green.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.species.graveler.desc": "Rocks are Graveler's favourite food. This Pokémon will climb a mountain from the base to the summit, crunchingly feasting on rocks all the while. Upon reaching the peak, it rolls back down to the bottom.",
"cobblemon.species.minior-blue.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.species.ducklett.desc": "They are better at swimming than flying, and they happily eat their favourite food, peat moss, as they dive underwater.",
"cobblemon.item_class.flavor_seasoning": "Flavour Seasoning",
"cobblemon.seasoning_flavor_header": "Flavour",
"cobblemon.seasoning_flavor_info_header": "Flavour Info:",
"cobblemon.ui.pokedex.info.form.color-light_gray": "Light Grey",
"cobblemon.ui.pokedex.info.form.color-gray": "Grey",
"advancements.cobblemon.first_shiny_catch": "Lucky Colour",
"advancements.cobblemon.obtain_all_mints.description": "Obtain all 6 colours of Nature Mint and gain access to a full array of natures",
"cobblemon.species.wartortle.desc": "Its tail is large and covered with a rich, thick fur. The tail becomes increasingly deeper in colour as Wartortle ages. The scratches on its shell are evidence of this Pokémon's toughness as a battler.",
"cobblemon.species.weedle.desc": "Weedle has an extremely acute sense of smell. It is capable of distinguishing its favourite kinds of leaves from those it dislikes just by sniffing with its big red proboscis (nose).",
"cobblemon.species.venomoth.desc": "Venomoth is nocturnal—it is a Pokémon that only becomes active at night. Its favourite prey are small insects that gather around streetlights, attracted by the light in the darkness.",
"cobblemon.species.muk.desc": "This Pokémon's favourite food is anything that is repugnantly filthy. In dirty towns where people think nothing of throwing away litter on the streets, Muk are certain to gather.",
"cobblemon.species.florges-white.desc": "A flower garden made by a white-flowered Florges will be beautifully decorated with flowering plants of many different colours.",
"cobblemon.species.deerling.desc": "The turning of the seasons changes the colour and scent of this Pokémon's fur. People use it to mark the seasons.",
"cobblemon.species.floette-orange.desc": "This Pokémon can draw forth the most power when in sync with orange flowers, compared to flowers of other colours.",
"cobblemon.species.floette-white.desc": "Floette that are fond of white flowers can also easily sync with flowers of other colours.",
"cobblemon.species.xerneas-active.desc": "When the horns on its head shine in seven colours, it is said to be sharing everlasting life.",
"cobblemon.species.gumshoos.desc": "Patient by nature, this Pokémon loses control of itself and pounces when it spots its favourite meal—Rattata!",
"cobblemon.species.minior-orange.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.species.minior-yellow.desc": "This is its form when its shell has fallen off. The colour of its core depends on the materials that made up the food it ate.",
"cobblemon.ui.pokedex.info.form.magearna-original": "Original Colour",
"cobblemon.species.polteageist-antique.desc": "Trainers Polteageist trusts will be allowed to experience its distinctive flavour and aroma firsthand by sampling just a tiny bit of its tea.",
"cobblemon.species.alcremie-matchacream.desc": "The moment it evolved, it took on an aromatic flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.alcremie-mintcream.desc": "The moment it evolved, it took on a refreshing flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.alcremie-lemoncream.desc": "The moment it evolved, it took on a sour flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.alcremie-saltedcream.desc": "The moment it evolved, it took on a salty flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.alcremie-rubyswirl.desc": "The moment it evolved, it took on a mixed flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.alcremie-caramelswirl.desc": "The moment it evolved, it took on a bitter flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.alcremie-rainbowswirl.desc": "The moment it evolved, it took on a complex flavour. This is because of the way its cells spontaneously shifted during evolution.",
"cobblemon.species.squawkabilly.desc": "These Pokémon prefer to live in cities. They form flocks based on the colour of their feathers, and they fight over territory.",
"cobblemon.species.tatsugiri-droopy.desc": "This species' differing colours and patterns are apparently the result of Tatsugiri changing itself to suit the preferences of the prey it lures in.",
"cobblemon.species.grafaiai.desc": "The colour of the poisonous saliva depends on what the Pokémon eats. Grafaiai covers its fingers in its saliva and draws patterns on trees in forests.",
"cobblemon.species.veluza.desc": "When Veluza discards unnecessary flesh, its mind becomes honed and its psychic power increases. The spare flesh has a mild but delicious flavour.",
"cobblemon.ability.colorchange": "Colour Change"
}
Loaded 100 of 202 files, more files were not shown because too many files have changed in this diff. Show more