Compare commits

...
135 Commits
Author SHA1 Message Date
JPAKx4 099bee8d5d Added jsons to resolve textures and en_us names. 2023-11-14 12:53:04 -06:00
JPAKx4 5a926ffa23 Added new hold items to registries and groups 2023-11-13 21:55:34 -06:00
JPAKx4 d7d32a186b Merge remote-tracking branch 'origin/HOLDY' into HOLDY
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation6/aromatisse.json
2023-11-13 20:54:56 -06:00
JPAKx4 f437b7a7ff Added new hold items to registries and groups 2023-11-13 20:53:08 -06:00
miasmusandJPAKx4 ff4ef2d90b changelog 2023-11-13 20:53:06 -06:00
miasmusandJPAKx4 5fb39bba2b data changes for new items, add to lang file 2023-11-13 20:52:59 -06:00
miasmusandJPAKx4 e4798e6793 Added items to registry and groups 2023-11-13 20:52:20 -06:00
dhi_holoandJPAKx4 ce6ef64cec Hold this for me please
47 new recipes and their advancements.
Ability Shield, Air Balloon, Amulet Coin, Binding Band, Blunder Policy, Cell Battery, Clear Amulet, Covert Cloak, Destiny Knot, Eject Button, Eject Pack, Expert Belt, Flame Orb, Focus Sash, Lagging Tail, Life Orb, Loaded Dice, Luminous Moss, Metronome, Pink Bow, Power Anklet, Power Band, Power Belt, Power Bracer, Power Lens, Power Weight, Protective Pads, Punching Glove, Red Card, Ring Target, Room Service, Scope Lens, Shell Bell, Soothe Bell, Terrain Extender, Throat Spray, Toxic Orb, Utility Umbrella, Weakness Policy, Heat Rock, Damp Rock, Icy Rock, Smooth Rock, Wide Lens, Zoom Lens, Iron Ball, and Bright Powder
2023-11-13 20:51:30 -06:00
Hiroku 9999a04692 Merge branch 'status-complete' into 'main'
added tab completion for Statuses

See merge request cable-mc/cobblemon!774
2023-11-13 06:29:19 +00:00
MoeBoy76 6901f3e43d added tab completion for Statuses 2023-11-13 17:07:22 +11:00
Hiroku 3b94b6660c Merge branch 'new_battle_fix' into 'main'
New 100+ Battle languages fixed

See merge request cable-mc/cobblemon!771
2023-11-12 08:55:05 +00:00
jeffw773 dc46c96ecf Fixed merge conflicts 2023-11-12 00:33:00 -08:00
Hiroku 55861a249e Merge branch 'augh-u-rite' into 'main'
More Augurite Usage

Closes #687

See merge request cable-mc/cobblemon!754
2023-11-12 03:28:42 +00:00
Hiroku f00a569d9d Merge branch 'main' into 'augh-u-rite'
# Conflicts:
#   CHANGELOG.md
2023-11-12 02:40:29 +00:00
Hiroku aaa5484752 Update CHANGELOG.md [skip-ci] 2023-11-12 01:38:44 +00:00
Hiroku c6e82ebfb9 Merge branch 'fix-405-recall-visual-bug' into 'main'
Fix visual Pokemon recall bug

Closes #415 and #405

See merge request cable-mc/cobblemon!750
2023-11-12 01:37:19 +00:00
Hiroku 365844ae2e Merge branch 'battle_text_fail_block' into 'main'
Added -fail and -block handlers to ShowdownInterpreter as well as added around...

See merge request cable-mc/cobblemon!753
2023-11-12 01:33:22 +00:00
Hiroku c18c1f39fb Merge branch 'main' into 'battle_text_fail_block'
# Conflicts:
#   CHANGELOG.md
2023-11-12 01:09:42 +00:00
Hiroku 1fd2aa06ae Merge branch 'EXP-Item-Pokemon-Select' into 'main'
Exp Candies - Party Pokemon Select

Closes #692

See merge request cable-mc/cobblemon!757
2023-11-11 22:55:31 +00:00
Hiroku 931852bd36 Merge branch 'alolanRatataFix' into 'main'
Fixed alolan Rattata animations

Closes #695

See merge request cable-mc/cobblemon!768
2023-11-11 19:48:25 +00:00
WaldleuferandHiroku 272f429f59 Fixed alolan Rattata animations 2023-11-11 19:48:24 +00:00
Hiroku 6a5c6d2b17 Merge branch 'licious/190' into 'main'
Conditional held item consumption

Closes #190

See merge request cable-mc/cobblemon!767
2023-11-11 12:37:16 +00:00
Hiroku 618453caaa Update CHANGELOG.md 2023-11-11 11:53:18 +00:00
Hiroku e1d048ec9d Merge branch 'main' into 'licious/190'
# Conflicts:
#   CHANGELOG.md
2023-11-11 11:52:37 +00:00
Hiroku 26ebd23d14 Merge branch 'sound' into 'main'
Added cries to the Beldum line, tweaked Pikachu and Raichu cries

See merge request cable-mc/cobblemon!766
2023-11-11 01:07:05 +00:00
Paul b446415200 Fixed minor position error in new pokeball animations 2023-11-11 09:45:47 +10:00
jeffw773 ed8fe19dc1 Fixed redundancies, added shared langs for a few moves, and fixed red formatting for fail lang. 2023-11-10 15:30:11 -08:00
dhi_holo e674b042d0 Nerfed Obsidian
reduced crafting to output 1 because it makes more sense
2023-11-11 08:49:21 +10:00
dhi_holo 53abb58ae6 Merge branch 'main' into augh-u-rite 2023-11-11 08:47:01 +10:00
Sterrezo 17fed9662c Merge branch 'main' into sound 2023-11-10 21:38:28 +01:00
Sterrezo 74dd2a6c0d Added cries to the Beldum line, tweaked Pikachu and Raichu cries 2023-11-10 21:38:11 +01:00
Stephen White 7505ce15e3 Merge remote-tracking branch 'upstream/main' into fix-405-recall-visual-bug 2023-11-10 12:27:43 -04:00
Charzard4261 30ba97ea69 Merge remote-tracking branch 'origin/EXP-Item-Pokemon-Select' into EXP-Item-Pokemon-Select 2023-11-10 14:15:20 +00:00
Charzard4261 5fee2df9f7 Added a missing POKEMON_INTERACT trigger in PokemonSelectingItem, when successfully using an Item on a Pokemon out of battle. 2023-11-10 14:14:53 +00:00
Charzard4261 238c7474b3 Merge branch 'main' into 'EXP-Item-Pokemon-Select'
# Conflicts:
#   CHANGELOG.md
2023-11-10 11:14:39 +00:00
Hiroku 5da5c72b4f Merge branch 'main' into 'main'
Restored Fabric BrewingStandBlockEntityMixin for brewing stand/sidehopper interaction

See merge request cable-mc/cobblemon!746
2023-11-10 05:55:58 +00:00
Hiroku 0604b45b9d Merge branch 'spectate' into 'main'
Added ability to spectate pokemon battles

See merge request cable-mc/cobblemon!747
2023-11-10 05:28:50 +00:00
ApionandHiroku 132a43c5c7 Added ability to spectate pokemon battles 2023-11-10 05:28:50 +00:00
Hiroku b1e8f9cfb6 Merge branch 'fortune_evo_ores' into 'main'
Fortune evo ores

Closes #686

See merge request cable-mc/cobblemon!765
2023-11-10 04:21:57 +00:00
Lily a166a38c4b Update CHANGELOG.md 2023-11-09 22:59:52 -05:00
Lily 57fa6a58d5 Add Fortune compatibility to evo stone ores. Closes #686 2023-11-09 22:58:39 -05:00
Charzard4261 95006ae327 Merge branch 'main' into 'EXP-Item-Pokemon-Select'
# Conflicts:
#   CHANGELOG.md
2023-11-10 00:08:03 +00:00
Hiroku ad6fc97eef Merge branch 'implement_pokemon' into 'main'
One new Pokémon line, Animation, Textures, and Models updated. Pokémon Sleep? Naw just sleepy Pokemon.

See merge request cable-mc/cobblemon!763
2023-11-10 00:03:21 +00:00
Tyzillion fc39baaa30 Fixed Exeggcute faint, Added emissive to Hoothoot. 2023-11-09 18:40:59 -05:00
Tyzillion 887ff8ccdb Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2023-11-09 18:29:47 -05:00
Paul 4d6117f5bf Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2023-11-10 09:13:44 +10:00
Paul 3dc26639a5 Fixed Trevenant sleep animation 2023-11-10 09:13:28 +10:00
Tyzillion 252f9d5dbd Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2023-11-09 16:46:47 -05:00
Charzard4261 599b8c5eec Merge branch 'main' into 'EXP-Item-Pokemon-Select'
# Conflicts:
#   CHANGELOG.md
2023-11-09 18:55:55 +00:00
Nick 974f839d61 Merge branch 'more_composting' into 'main'
Update composting functionality for Heal Powder and mutated Herbs

Closes #681

See merge request cable-mc/cobblemon!759
2023-11-09 18:50:44 +00:00
Nick b4ea13ab20 Merge branch 'milk_the_mooshtank' into 'main'
Allow Mooshtanks to be milked for mushroom stew. Closes #684

Closes #684

See merge request cable-mc/cobblemon!758
2023-11-09 18:49:33 +00:00
Nick 06afb04050 Merge branch 'missing_messages' into 'main'
Added a bunch of missing texts. Fixes #582, #588

Closes #588 and #582

See merge request cable-mc/cobblemon!752
2023-11-09 18:48:25 +00:00
Lily 92c3d9464b Merge branch 'main' into milk_the_mooshtank
# Conflicts:
#	CHANGELOG.md
2023-11-09 13:04:53 -05:00
Lily 03ed8f3edd Update CHANGELOG.md 2023-11-09 13:03:23 -05:00
Hiroku b475b02fff Merge branch 'Bee-Related-Changes' into 'main'
Bee Related Changes

See merge request cable-mc/cobblemon!762
2023-11-08 20:10:18 +00:00
Charzard4261 8c462f1567 Gave the Pep-Up Flower item the "minecraft:flowers" tag, to allow Bees to be fed using them. 2023-11-08 16:23:16 +00:00
Lily e668735dd8 Update composting functionality for Heal Powder and mutated Herbs. Closes #681 2023-11-07 21:15:22 -05:00
Lily f0e65fe4de Allow Mooshtanks to be milked for mushroom stew. Closes #684 2023-11-07 20:41:19 -05:00
Charzard4261 084a7bfb3c CandyItem now uses PokemonSelectingItem, and does not consume when in Creative. 2023-11-08 00:46:51 +00:00
Tyzillion 3c11a673dc Update models for Hitmontop. Updated animations for Zubat, Golbat, Scatterbug, Spewpa. Added Shoulder animations for Zubat. 2023-11-07 07:23:36 -05:00
dhi_holo deb2cff477 A Use?
Augurite now can make axes and obsidian, closes #687
2023-11-07 12:16:30 +10:00
jeffw773 79d89852d4 Added -fail and -block handlers to ShowdownInterpreter as well as added around 17 battle texts related to them 2023-11-06 15:51:09 -08:00
Tyzillion 8d38144551 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2023-11-06 14:08:39 -05:00
Stephen White a21a172be3 Fix visual Pokemon recall bug 2023-11-06 10:32:05 -04:00
JazzMcNade b44e5c797e Made sure mixin logic is applied for all potion slots in brewing stands. 2023-11-05 17:12:15 -06:00
JazzMcNade ae9337c84a Mixin compatibility changes. 2023-11-05 16:33:44 -06:00
JazzMcNade 5db2c4c955 Restored BrewingStandBlockEntityMixin for brewing stand/hopper interaction 2023-11-05 03:59:54 -06:00
Hiroku 8af1225c90 Merge branch 'npc-revival' into 'main'
Prevent NPCs from freezing battles upon using Revival Blessing.

See merge request cable-mc/cobblemon!745
2023-11-05 05:14:51 +00:00
jmmcp 4b181d75c8 Added a check to avoid NPCs freezing battles upon using Revival Blessing. 2023-11-05 00:51:38 -04:00
Hiroku 9e28dce3d7 Merge branch 'revival-blessing-fix' into 'main'
Fixes the move Revival Blessing

Closes #660

See merge request cable-mc/cobblemon!744
2023-11-05 02:29:27 +00:00
jmmcp 39f084bd56 Can't forget the changelog. 2023-11-04 21:46:29 -04:00
jmmcp c82bba7872 Add checks throughout the switch process to allow the Revival Blessing forceSwitch command to validate. 2023-11-04 21:42:03 -04:00
Hiroku 3f557d9ae6 Merge branch 'return_bottles' into 'main'
Return bottles

Closes #674 and #673

See merge request cable-mc/cobblemon!742
2023-11-04 04:35:26 +00:00
Tyzillion c15976a936 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2023-11-03 21:38:04 -04:00
Hiroku c8652b519a Merge branch 'vivillon_wings' into 'main'
Implement new Vivillon patterns

Closes #600 and #676

See merge request cable-mc/cobblemon!743
2023-11-04 00:51:32 +00:00
Lily 67c828dd0c missed one 2023-11-03 19:49:30 -04:00
Lily 10a1bc6bc6 Merge remote-tracking branch 'origin/return_bottles' into return_bottles 2023-11-03 19:42:35 -04:00
Lily e4db065a85 change friendshop drop through json and not the item class 2023-11-03 19:42:09 -04:00
Hiroku 171cd45e32 Merge branch 'main' into 'return_bottles'
# Conflicts:
#   CHANGELOG.md
2023-11-03 23:27:57 +00:00
Lily d638315fb1 Rename "Patterned Wings" to "Vivillonaire". Closes #676 2023-11-03 19:27:38 -04:00
Hiroku 980fa6a13d Merge branch 'healing_percent_fix' into 'main'
Fix issue involving health display after healing

Closes #663

See merge request cable-mc/cobblemon!740
2023-11-03 23:27:37 +00:00
Hiroku 267faf9397 Merge branch 'get-nerfed' into 'main'
Harder Healing Machine, Nerds

Closes #672

See merge request cable-mc/cobblemon!741
2023-11-03 23:25:56 +00:00
Lily 7549d77ad7 Update CHANGELOG.md 2023-11-03 19:24:59 -04:00
Lily 0f6929dd5e implement new vivillon wing patterns. Closes #600 2023-11-03 19:23:18 -04:00
Licious 79597a81fe Implemented conditional held item consumption. 2023-11-03 11:44:42 +00:00
dhi_holo e54e822c3a Harder Healing Machine, Nerds
Closes #672
2023-11-03 15:12:30 +10:00
Lily 5e60bb525c Changes to healing items. Closes #673, #674 2023-11-02 23:47:12 -04:00
Tyzillion c49cb45892 Fixed sleeping animations not playing for many Pokmeon. Implemented Litwick line, Update model, texture, and animations for Zubat line. Fixed Ceruledge back spike texture error. Updated Dusknoir, Ratatta, and Exegguter animation. Fixed Volbeat t-pose when flying. Fixed Wimpod asymmetric eyebrows. Fixed Voltorb texture. Fixed shiny Pidgeotto texture. 2023-11-02 22:22:16 -04:00
Tyzillion e0a896377e Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2023-11-02 22:19:43 -04:00
Lily b96638226c Fixes #663 2023-11-02 22:19:36 -04:00
Lily 7c025582e0 Added a bunch of missing texts. Fixes #582, #588 2023-11-02 19:59:52 -04:00
Hiroku 623dfbb78b Merge branch 'licious/potion-fixes' into 'main'
Rework potion stuff & fixes

Closes #667 and #460

See merge request cable-mc/cobblemon!739
2023-11-02 23:28:37 +00:00
Licious 942bf8247e Consistent names aren't my specialty okay? 2023-11-02 22:44:26 +00:00
Licious d6a991e81e Fix various potion related issues. 2023-11-02 22:43:33 +00:00
Tyzillion 5d5de4f2f3 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon
# Conflicts:
#	CHANGELOG.md
2023-11-02 15:38:50 -04:00
Hiroku 7e952295a5 Merge branch 'licious/a-sign-of-boats-to-come' into 'main'
Implement Apricorn boats & signs

See merge request cable-mc/cobblemon!725
2023-11-02 08:14:26 +00:00
Hiroku d299cad9db Merge branch 'main' into 'licious/a-sign-of-boats-to-come'
# Conflicts:
#   CHANGELOG.md
2023-11-01 20:35:35 +00:00
Nick 261408d542 Merge branch 'licious/606' into 'main'
Progress related evolution requirement fixes

Closes #606

See merge request cable-mc/cobblemon!738
2023-11-01 19:01:24 +00:00
Nick cde163c1d1 Merge branch 'licious/597' into 'main'
Fix loot injection on Forge

Closes #597

See merge request cable-mc/cobblemon!736
2023-11-01 16:52:54 +00:00
Licious dbc478fc89 Fix battle critical hits evolution, fixed DamageTakenEvolutionProgress & DefeatEvolutionProgress not being registered. 2023-11-01 14:49:03 +00:00
Licious dde6c1dc97 *Apricorn 2023-10-31 23:47:46 +00:00
Licious 41d7740374 Merge branch 'main' into licious/a-sign-of-boats-to-come
# Conflicts:
#	CHANGELOG.md
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonItems.kt
#	common/src/main/resources/mixins.cobblemon-common.json
2023-10-31 23:44:21 +00:00
Licious 29f0c6f7bc Rework LootInjector functionality, fix Forge. 2023-10-31 23:38:17 +00:00
Licious d128d3e025 Merge branch 'blame-json' into 'main'
Advancements Fixed

See merge request cable-mc/cobblemon!735
2023-10-31 09:50:59 +00:00
Licious 422bd5a0de Merge branch 'licious/596' into 'main'
Add the Fairy Feather.

Closes #596

See merge request cable-mc/cobblemon!734
2023-10-31 09:50:28 +00:00
Licious 65271dc1b1 Merge branch 'licious/595' into 'main'
Add the Cleanse Tag item

Closes #595

See merge request cable-mc/cobblemon!733
2023-10-31 09:50:07 +00:00
dhi_holo 8a604fdefe Only Canon
Removed Cobblemon Vivillon patterns from advancement for time being, so this can be merged
2023-10-31 12:15:26 +10:00
dhi_holo a525df98cd Merge branch 'main' into blame-json 2023-10-31 12:14:19 +10:00
Licious 6a5c52ca0e Add the Fairy Feather. 2023-10-30 11:40:47 +00:00
Licious 57509b6bba Fix typo. 2023-10-30 11:21:27 +00:00
Licious 0a4b7fe5c8 Added the cleanse tag. 2023-10-30 11:21:19 +00:00
Hiroku 45f72e0e9e Merge branch 'spawner-fixes' into 'main'
Two spawner fixes

See merge request cable-mc/cobblemon!732
2023-10-30 07:30:06 +00:00
Deltric 029e152d95 Updated changelog for spawning fixes. 2023-10-30 02:00:22 -05:00
Deltric 08d6fa00eb Two spawner fixes 2023-10-30 01:47:36 -05:00
Hiroku 35bb803fb0 Merge branch 'battle-lang-fix' into 'main'
Battle lang fix

Closes #617 and #637

See merge request cable-mc/cobblemon!731
2023-10-29 23:48:38 +00:00
Plastered_Crab ec028c89e4 Update CHANGELOG.md 2023-10-29 18:47:27 +00:00
Plastered_Crab 1de8a40bae Added case for Disable to ShowdownInterpreter.kt 2023-10-29 18:45:24 +00:00
Plastered_Crab 8c682356bb Added extra battle text for various moves en_us.json 2023-10-29 18:42:33 +00:00
dhi_holo f7adaa6100 Moving recipes to correct root (4/4) 2023-10-29 01:16:51 +00:00
dhi_holo 7381ef6a02 Moving recipes to correct root (3/4) 2023-10-29 01:16:36 +00:00
dhi_holo a54acc48e7 Moving recipes to correct root (2/4) 2023-10-29 01:16:14 +00:00
dhi_holo 5478db4e32 Moving recipes to correct root (1/4) 2023-10-29 01:15:59 +00:00
Licious 5f55cbb5d3 Implement Apricorn boats & signs, pending texture approval. Fix a few missing item tags in CobblemonItemTags. Added support for injecting into specific points of ItemGroups. 2023-10-28 15:20:08 +01:00
tyzillion dfa104d8cf Updated Pokeball animations and model tweaks.
- Added cries to Raticate, Onix, Unfezant, Bergmite, Avalugg, Boltund, Revavroom.
- Turtwig can now be put on shoulder.
- Added animations for Hitmontop, Tyrogue, and Mightyena.
- Tweaked animations for Bewear, Exeggutor, and Alolan Exeggutor.
- Sized Kantonian Exeggutor down. Still big but not TOO BIG.
2023-10-26 15:07:39 -04:00
tyzillion 6ff53c0be3 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2023-10-26 15:04:49 -04:00
dhi_holo 088159bab2 Advancements Fixed
Repairs harvest_apricorn_seed and catch_all_vivillon advancements (can't be merged until confirmation on whether the Vivillon forms are ready for 1.4.1 or not)
2023-10-26 16:02:23 +10:00
tyzillion 6682049be1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2023-10-25 20:17:49 -04:00
tyzillion fa2bbdbb10 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2023-10-25 20:17:02 -04:00
Sterrezo 2798f73397 Fixed a couple missing cries
Fixed typo in farfetchd_galar.animation.json, added a cry provider to QuaxwellModel.kt, added a placeholder cry for Raticate, added missing sound keyframes to Onix, Unfezant, Bergmite, Avalugg, Boltund, Revavroom
2023-10-21 20:13:25 +02:00
miasmus 6d52b8f690 changelog 2023-10-20 12:45:32 -04:00
miasmus b1c804d567 data changes for new items, add to lang file 2023-10-19 17:29:02 -04:00
miasmus b386d1a806 added cleanse tag and fairy feather, edit relevant species drops 2023-10-19 17:28:36 -04:00
miasmus 01ea8daedf Merge remote-tracking branch 'origin/main' into HOLDY
# Conflicts:
#      CHANGELOG.md
#      destiny_knot.json
2023-10-19 17:23:43 -04:00
Paul a449396dc3 Merge remote-tracking branch 'origin/main' into HOLDY
# Conflicts:
#	CHANGELOG.md
2023-09-03 13:26:30 +10:00
dhi_holo ed3b0e9630 Hold this for me please
47 new recipes and their advancements.
Ability Shield, Air Balloon, Amulet Coin, Binding Band, Blunder Policy, Cell Battery, Clear Amulet, Covert Cloak, Destiny Knot, Eject Button, Eject Pack, Expert Belt, Flame Orb, Focus Sash, Lagging Tail, Life Orb, Loaded Dice, Luminous Moss, Metronome, Pink Bow, Power Anklet, Power Band, Power Belt, Power Bracer, Power Lens, Power Weight, Protective Pads, Punching Glove, Red Card, Ring Target, Room Service, Scope Lens, Shell Bell, Soothe Bell, Terrain Extender, Throat Spray, Toxic Orb, Utility Umbrella, Weakness Policy, Heat Rock, Damp Rock, Icy Rock, Smooth Rock, Wide Lens, Zoom Lens, Iron Ball, and Bright Powder
2023-06-26 13:36:05 +10:00
537 changed files with 21646 additions and 3881 deletions
+63 -11
View File
@@ -3,19 +3,50 @@
### Changes
- Slightly lowered the volume of all cries
- Updated Pokeball animations and model.
- Turtwig can now be put on shoulder.
- Updated Zubat line model, texture, and animations.
- Added animations for Hitmontop, Tyrogue, and Mightyena.
- Tweaked animations for Dusknoir, Ratatta, Bewear, Exeggutor, and Alolan Exeggutor.
- Sized Kantonian Exeggutor down. Still big but not TOO BIG.
- Tweaked cries for Pikachu, Raichu and Alolan Raichu.
- Pasture blocks will now also connect their bottom left and right sides to walls, iron bars, glass panes and any other modded block that follows the same connection rules.
- The config option `consumeHeldItems` has been removed, please see the Datapack & Resourcepack Creators for instructions on the updated method.
- Using Potions, Status Heals, Ethers, and Antidotes will now return a glass bottle
- Using a Remedy, Fine Remedy, or Superb Remedy will no longer lower friendship with a Pokémon
- The Healing Machine now has a more difficult recipe, placing it later game.
- Heal Powder can now be composted with a 75% chance of adding a layer
- Mental, Power, White, and Mirror Herbs can now be composted with a 100% chance of adding a layer.
- Added emissive to Hoothoot.
- Mining Evolution Stone Ores with a Fortune pickaxe will now increase the amount of items recieved
- Black Augurite can now be used to craft stone axes and obsidian.
- Using Experience Candies brings up the Party Pokémon Select screen when not targeting a Pokémon.
- Added tab completion for statuses to commands
### Additions
- Added battle spectating, can disable in config
- Cobblemon now has compatibility with [Adorn](https://modrinth.com/mod/adorn) allowing you to craft Apricorn wood furniture.
- Berries can now be used in recipes from [Farmer's Delight](https://modrinth.com/mod/farmers-delight) and [Farmer's Delight (Fabric)](https://modrinth.com/mod/farmers-delight-fabric), as well as any other mods using the same berry tags.
- The nature of cobblemon will now be displayed italicized when a mint has been applied. Hovering over the nature will display the mint that was applied. This is the intended behaviour, because the original nature and taste of the Cobblemon does not change when a mint is applied.
- Giving Pokémon items now plays a sound
- A boat, sign and hanging sign is now craftable with Apricorn wood. The recipes are the same shape as Minecraft's equivalent with Apricorn planks as replacements.
- Added the [Cleanse Tag](https://wiki.cobblemon.com/index.php/Cleanse_Tag) and [Fairy Feather](https://wiki.cobblemon.com/index.php/Fairy_Feather)
- Added Fairy Feather drops to some pokemon
- Added the Inferno, Void, and Forsaken patterns for Vivillon. These can be obtained by evolving a Spewpa in the Nether, End, or Deep Dark respectively.
- Added the Litwick line.
- Bees can now be fed using Pep-Up Flowers.
- Mooshtank can now be milked with a bowl for Mushroom Stew.
- Added cries to Beldum, Metang and Metagross.
### Fixes
- Fixed various stone related blocks not being valid for Big Roots to spread on the Fabric version.
- Updated the registration of compostable items to improve compatibility with Fabric forks such as Quilt. Please note this does not mean we officially support Quilt, this change was only done since it was possible by correcting the registration to use the new intended way in the Fabric API.
- Fixed Dispensers being unable to shear grown Apricorns.
- Fixed Bowl not being given back to player after using Berry Juice
- Added context for -fail and -block handlers for battle text and added 16 related battle texts for them
- Fixed Battle text for Disable, Laser Focus, Foresight, Fire Spin, Telekinesis, Curse, Recharge and Encore
- Fixed missing text for snowy weather in battles
- Fixed missing text for attempting to catch an uncatchable Pokémon
- Fixed Moonphases for Clefairy line
- Fixed issue where Potions, Super Potions, and Hyper Potions did not work during battle
- Fixed the compatibility patch with the Forge version of [Carry On](https://modrinth.com/mod/carry-on) due to a bug on the mod, the Fabric version was unchanged and is still compatible.
@@ -29,10 +60,31 @@
- Fixed cursed battle message
- Fixed mistakes in pokemon spawning JSONs
- Fixed advancement crash from bad datapack evolution data.
- Fixed global influences being applied to TickingSpawners twice.
- Reverted the default SpawningSelector back to FlatContextWeightedSelector. This fixes multiple weight related issues, including weights with SpawningInfluences.
- Apricorn Planting advancement should work again.
- Advancement "Patterned Wings" should now allow High Plains and Icy Snow Vivillon to register.
- Fixed the last battle critical hits evolution requirement not working.
- Fixed the damage taken evolution requirement not saving progress.
- Fixed the defeated Pokémon evolution requirement not saving progress.
- Fixed potion brewing recipes not showing up JEI and similar mods on the Forge version.
- Fixed an exploit that could convert a single piece of Blaze Powder into an extra Medicinal Brew on the Forge version.
- Fixed an issue where health percentages would show incorrectly after healing
- Fixed the move Revival Blessing not allowing you to select from fainted party members.
- Fixed Exeggcute faint.
- Fixed Raticate, Onix, Unfezant, Bergmite, Avalugg, Boltund and Revavroom cries not playing.
- Fixed Alolan Ratticate animations causing a crash.
- Fixed Quaxwell not doing its cry.
- Fixed Shroomish not using its idle.
- Fixed a possible visual duplication of sent out Pokémon.
### Developer
- Fixed the `SpawnEvent` not respecting usage of `Cancelable#cancel`.
- Added the `EvolutionTestedEvent`, this allows listening and overriding the final result of evolution requirement tests.
- The `HeldItemManager` has a new method `shouldConsumeItem`, this will return false by default to prevent breaking changes, see the documentation and update your implementations as needed.
### Datapack & Resourcepack Creators
- Added 3 new item tags: `cobblemon:held/consumed_in_npc_battle`, `cobblemon:held/consumed_in_pvp_battle` & `cobblemon:held/consumed_in_wild_battle` these will determine which items get consumed in the implied battle types by Cobblemon, keep in mind the controller for this behaviour can be overriden by 3rd party.
## [1.4.0 - The Friends and Farms Update (October 13th, 2023)](#1-4-0)
### Additions
@@ -441,7 +493,7 @@
- Species and FormData have had their evolutions, pre-evolution and labels properties exposed. It is still recommended to work using a Pokémon instance when possible.
- Added capture check to BattleVictoryEvent.
- The various hardcoded potion shoulder effects have been removed, make use of PotionBaseEffect.
- Added ContextManager for tracking causes and contexts of conditions created during a battle. See BattleContext for types of conditions that are tracked.
- Added ContextManager for tracking causes and contexts of conditions created during a battle. See BattleContext for types of conditions that are tracked.
- Added MongoDB support for storing Pokémon and Player data. Must be enabled in config, requires MongoDB core and sync drivers (4.10.0+).
- CobblemonShowdown updated to version 10.
- Generation of a battle can be set in BattleFormat.
@@ -821,17 +873,17 @@
- Fixed spawning in several biome tag categories.
- Fixed resource pack support for Pokémon models and textures.
- **Model Fixes**
- Fixed Paras and Nidoqueen looking very weird.
- Fixed Hitmonchan asserting dominance with a T-pose as well as Grimer and Muk pointing their hands to the sky.
- Fixed specific Pokémon suddenly pausing their animation after staying still for a long time.
- Fixed Mankey's feet being buried in the ground.
- Updated the Substitute model and updated its shiny texture to be better for the red-green colorblind.
- Improved Horsea, Seadra, and Kingdra animations, especially on land.
- Fixed Paras and Nidoqueen looking very weird.
- Fixed Hitmonchan asserting dominance with a T-pose as well as Grimer and Muk pointing their hands to the sky.
- Fixed specific Pokémon suddenly pausing their animation after staying still for a long time.
- Fixed Mankey's feet being buried in the ground.
- Updated the Substitute model and updated its shiny texture to be better for the red-green colorblind.
- Improved Horsea, Seadra, and Kingdra animations, especially on land.
- **Battle Fixes**
- Fixed an issue with battles where Pokémon had a different max HP causing some desync issues with the health bars.
- Fixed Magnitude battle messages.
- Moves that are disabled or out of PP now show transparently in the battle GUI instead of being hidden completely.
- Statuses like sleep and frozen no longer last forever if it was carried over from a previous battle.
- Fixed an issue with battles where Pokémon had a different max HP causing some desync issues with the health bars.
- Fixed Magnitude battle messages.
- Moves that are disabled or out of PP now show transparently in the battle GUI instead of being hidden completely.
- Statuses like sleep and frozen no longer last forever if it was carried over from a previous battle.
### Localization
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
@@ -6,21 +6,18 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.forge.mixin.accessor;
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.loot.LootPool;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.function.LootFunction;
import net.minecraft.entity.vehicle.BoatEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(LootTable.Builder.class)
public interface LootTableBuilderAccessor {
@Accessor
List<LootPool> getPools();
@Mixin(BoatEntity.class)
public interface BoatEntityAccessor {
@Accessor
List<LootFunction> getFunctions();
void setFallVelocity(double fallVelocity);
@Accessor
BoatEntity.Location getLocation();
}
@@ -8,10 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
import com.cobblemon.mod.common.block.entity.PCBlockEntity
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
import com.cobblemon.mod.common.block.entity.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.registry.Registries
@@ -31,5 +28,9 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
val BERRY = this.create("berry", BlockEntityType.Builder.create(::BerryBlockEntity, *CobblemonBlocks.berries().values.toTypedArray()).build(null))
@JvmField
val PASTURE: BlockEntityType<PokemonPastureBlockEntity> = this.create("pasture", BlockEntityType.Builder.create(::PokemonPastureBlockEntity, CobblemonBlocks.PASTURE).build(null))
@JvmField
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.create(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN).build(null))
@JvmField
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.create(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN).build(null))
}
@@ -19,6 +19,10 @@ import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import net.minecraft.block.*
import net.minecraft.block.piston.PistonBehavior
import net.minecraft.entity.effect.StatusEffects
@@ -107,9 +111,14 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD), APRICORN_BLOCK_SET_TYPE))
// Tag was removed be sure to add it back when implemented
//val APRICORN_SIGN = queue("apricorn_sign") { StandingSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE) }
//val APRICORN_WALL_SIGN = queue("apricorn_wall_sign") { WallSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD).dropsLike(APRICORN_SIGN), APRICORN_WOOD_TYPE) }
@JvmField
val APRICORN_SIGN = this.create("apricorn_sign", CobblemonSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_WALL_SIGN = this.create("apricorn_wall_sign", CobblemonWallSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_WALL_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_HANGING_SIGN = this.create("apricorn_hanging_sign", CobblemonHangingSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_WALL_HANGING_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_WALL_HANGING_SIGN = this.create("apricorn_wall_hanging_sign", CobblemonWallHangingSignBlock(AbstractBlock.Settings.copy(Blocks.OAK_HANGING_SIGN), APRICORN_WOOD_TYPE))
@JvmField
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
@JvmField
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common
import java.util.function.Supplier
import net.minecraft.block.Block
import net.minecraft.block.entity.BlockEntity
import net.minecraft.block.entity.BlockEntityType
@@ -19,11 +18,14 @@ import net.minecraft.client.particle.ParticleFactory
import net.minecraft.client.particle.SpriteProvider
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.model.EntityModelLayer
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.item.Item
import net.minecraft.particle.ParticleEffect
import net.minecraft.particle.ParticleType
import net.minecraft.resource.SynchronousResourceReloader
import java.util.function.Supplier
interface CobblemonClientImplementation {
fun registerLayer(modelLayer: EntityModelLayer, supplier: Supplier<TexturedModelData>)
@@ -38,5 +40,7 @@ interface CobblemonClientImplementation {
fun registerBlockColors(provider: BlockColorProvider, vararg blocks: Block)
fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<T>, factory: BlockEntityRendererFactory<T>)
fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<out T>, factory: BlockEntityRendererFactory<T>)
fun <T : Entity> registerEntityRenderer(type: EntityType<out T>, factory: EntityRendererFactory<T>)
}
@@ -9,6 +9,8 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonChestBoatEntity
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.platform.PlatformRegistry
@@ -45,6 +47,24 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, RegistryKey
.build(EMPTY_POKEBALL_KEY.toString())
)
@JvmField
val BOAT_KEY = cobblemonResource("boat")
@JvmField
val BOAT: EntityType<CobblemonBoatEntity> = this.create(
BOAT_KEY.path,
EntityType.Builder.create(::CobblemonBoatEntity, SpawnGroup.MISC).setDimensions(1.375F, 0.5625F).maxTrackingRange(10)
.build(BOAT_KEY.toString())
)
@JvmField
val CHEST_BOAT_KEY = cobblemonResource("chest_boat")
@JvmField
val CHEST_BOAT: EntityType<CobblemonChestBoatEntity> = this.create(
CHEST_BOAT_KEY.path,
EntityType.Builder.create(::CobblemonChestBoatEntity, SpawnGroup.MISC).setDimensions(1.375F, 0.5625F).maxTrackingRange(10)
.build(CHEST_BOAT_KEY.toString())
)
fun registerAttributes(consumer: (EntityType<out LivingEntity>, DefaultAttributeContainer.Builder) -> Unit) {
consumer(POKEMON, PokemonEntity.createAttributes())
}
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.MintBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.item.*
import com.cobblemon.mod.common.item.battle.DireHitItem
import com.cobblemon.mod.common.item.battle.GuardSpecItem
@@ -123,34 +124,34 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val VIVICHOKE_SEEDS = compostableItem("vivichoke_seeds", VivichokeItem(CobblemonBlocks.VIVICHOKE_SEEDS))
@JvmField
val RED_APRICORN = apricronItem("red", ApricornItem(CobblemonBlocks.RED_APRICORN))
val RED_APRICORN = apricornItem("red", ApricornItem(CobblemonBlocks.RED_APRICORN))
@JvmField
val YELLOW_APRICORN = apricronItem("yellow", ApricornItem(CobblemonBlocks.YELLOW_APRICORN))
val YELLOW_APRICORN = apricornItem("yellow", ApricornItem(CobblemonBlocks.YELLOW_APRICORN))
@JvmField
val GREEN_APRICORN = apricronItem("green", ApricornItem(CobblemonBlocks.GREEN_APRICORN))
val GREEN_APRICORN = apricornItem("green", ApricornItem(CobblemonBlocks.GREEN_APRICORN))
@JvmField
val BLUE_APRICORN = apricronItem("blue", ApricornItem(CobblemonBlocks.BLUE_APRICORN))
val BLUE_APRICORN = apricornItem("blue", ApricornItem(CobblemonBlocks.BLUE_APRICORN))
@JvmField
val PINK_APRICORN = apricronItem("pink", ApricornItem(CobblemonBlocks.PINK_APRICORN))
val PINK_APRICORN = apricornItem("pink", ApricornItem(CobblemonBlocks.PINK_APRICORN))
@JvmField
val BLACK_APRICORN = apricronItem("black", ApricornItem(CobblemonBlocks.BLACK_APRICORN))
val BLACK_APRICORN = apricornItem("black", ApricornItem(CobblemonBlocks.BLACK_APRICORN))
@JvmField
val WHITE_APRICORN = apricronItem("white", ApricornItem(CobblemonBlocks.WHITE_APRICORN))
val WHITE_APRICORN = apricornItem("white", ApricornItem(CobblemonBlocks.WHITE_APRICORN))
@JvmField
val RED_APRICORN_SEED = apricronSeedItem("red", ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING))
val RED_APRICORN_SEED = apricornSeedItem("red", ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING))
@JvmField
val YELLOW_APRICORN_SEED = apricronSeedItem("yellow", ApricornSeedItem(CobblemonBlocks.YELLOW_APRICORN_SAPLING))
val YELLOW_APRICORN_SEED = apricornSeedItem("yellow", ApricornSeedItem(CobblemonBlocks.YELLOW_APRICORN_SAPLING))
@JvmField
val GREEN_APRICORN_SEED = apricronSeedItem("green", ApricornSeedItem(CobblemonBlocks.GREEN_APRICORN_SAPLING))
val GREEN_APRICORN_SEED = apricornSeedItem("green", ApricornSeedItem(CobblemonBlocks.GREEN_APRICORN_SAPLING))
@JvmField
val BLUE_APRICORN_SEED = apricronSeedItem("blue", ApricornSeedItem(CobblemonBlocks.BLUE_APRICORN_SAPLING))
val BLUE_APRICORN_SEED = apricornSeedItem("blue", ApricornSeedItem(CobblemonBlocks.BLUE_APRICORN_SAPLING))
@JvmField
val PINK_APRICORN_SEED = apricronSeedItem("pink", ApricornSeedItem(CobblemonBlocks.PINK_APRICORN_SAPLING))
val PINK_APRICORN_SEED = apricornSeedItem("pink", ApricornSeedItem(CobblemonBlocks.PINK_APRICORN_SAPLING))
@JvmField
val BLACK_APRICORN_SEED = apricronSeedItem("black", ApricornSeedItem(CobblemonBlocks.BLACK_APRICORN_SAPLING))
val BLACK_APRICORN_SEED = apricornSeedItem("black", ApricornSeedItem(CobblemonBlocks.BLACK_APRICORN_SAPLING))
@JvmField
val WHITE_APRICORN_SEED = apricronSeedItem("white", ApricornSeedItem(CobblemonBlocks.WHITE_APRICORN_SAPLING))
val WHITE_APRICORN_SEED = apricornSeedItem("white", ApricornSeedItem(CobblemonBlocks.WHITE_APRICORN_SAPLING))
@JvmField
val APRICORN_LOG = blockItem("apricorn_log", CobblemonBlocks.APRICORN_LOG)
@@ -164,6 +165,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val APRICORN_PLANKS = blockItem("apricorn_planks", CobblemonBlocks.APRICORN_PLANKS)
@JvmField
val APRICORN_LEAVES = compostableBlockItem("apricorn_leaves", CobblemonBlocks.APRICORN_LEAVES)
@JvmField
val APRICORN_BOAT = create("apricorn_boat", CobblemonBoatItem(CobblemonBoatType.APRICORN, false, Item.Settings().maxCount(1)))
@JvmField
val APRICORN_CHEST_BOAT = create("apricorn_chest_boat", CobblemonBoatItem(CobblemonBoatType.APRICORN, true, Item.Settings().maxCount(1)))
@JvmField
val APRICORN_DOOR = blockItem("apricorn_door", CobblemonBlocks.APRICORN_DOOR)
@@ -177,12 +182,14 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val APRICORN_BUTTON = blockItem("apricorn_button", CobblemonBlocks.APRICORN_BUTTON)
@JvmField
val APRICORN_PRESSURE_PLATE = blockItem("apricorn_pressure_plate", CobblemonBlocks.APRICORN_PRESSURE_PLATE)
//@JvmField
// val APRICORN_SIGN = create("apricorn_sign", SignItem(Item.Properties().stacksTo(16).tab(CreativeModeTab.TAB_DECORATIONS), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
@JvmField
val APRICORN_SLAB = blockItem("apricorn_slab", CobblemonBlocks.APRICORN_SLAB)
@JvmField
val APRICORN_STAIRS = blockItem("apricorn_stairs", CobblemonBlocks.APRICORN_STAIRS)
@JvmField
val APRICORN_SIGN = this.create("apricorn_sign", SignItem(Item.Settings().maxCount(16), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
@JvmField
val APRICORN_HANGING_SIGN = this.create("apricorn_hanging_sign", HangingSignItem(CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN, Item.Settings().maxCount(16)))
@JvmField
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE)
@@ -564,10 +571,14 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val CHOICE_SPECS = heldItem("choice_specs")
@JvmField
val CLEANSE_TAG = heldItem("cleanse_tag")
@JvmField
val DRAGON_FANG = heldItem("dragon_fang")
@JvmField
val EXP_SHARE = heldItem("exp_share")
@JvmField
val FAIRY_FEATHER = heldItem("fairy_feather")
@JvmField
val FOCUS_BAND = heldItem("focus_band")
@JvmField
val HARD_STONE = heldItem("hard_stone")
@@ -612,18 +623,20 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
@JvmField
val WISE_GLASSES = heldItem("wise_glasses")
@JvmField
val MENTAL_HERB = compostableHeldItem("mental_herb")
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 1F)
@JvmField
val MIRROR_HERB = compostableHeldItem("mirror_herb")
val MIRROR_HERB = compostableHeldItem("mirror_herb", null, 1F)
@JvmField
val POWER_HERB = compostableHeldItem("power_herb")
val POWER_HERB = compostableHeldItem("power_herb", null, 1F)
@JvmField
val WHITE_HERB = heldItem("white_herb")
val WHITE_HERB = compostableHeldItem("white_herb", null, 1F)
@JvmField
val BRIGHT_POWDER = heldItem("bright_powder")
@JvmField
val METAL_POWDER = heldItem("metal_powder")
@JvmField
val LIGHT_POWDER = heldItem("light_powder")
@JvmField
val QUICK_POWDER = heldItem("quick_powder")
@JvmField
val DESTINY_KNOT = heldItem("destiny_knot")
@@ -641,6 +654,104 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
val POWER_LENS = heldItem("power_lens")
@JvmField
val POWER_WEIGHT = heldItem("power_weight")
@JvmField
val ABSORB_BULB = heldItem("absorb_bulb")
@JvmField
val ELECTRIC_SEED = heldItem("electric_seed")
@JvmField
val GRASSY_SEED = heldItem("grassy_seed")
@JvmField
val MISTY_SEED = heldItem("misty_seed")
@JvmField
val PSYCHIC_SEED = heldItem("psychic_seed")
@JvmField
val FLOAT_STONE = heldItem("float_stone")
@JvmField
val GRIP_CLAW = heldItem("grip_claw")
@JvmField
val LIGHT_BALL = heldItem("light_ball")
@JvmField
val SHED_SHELL = heldItem("shed_shell")
@JvmField
val STICKY_BARB = heldItem("sticky_barb")
@JvmField
val ABILITY_SHIELD = heldItem("ability_shield")
@JvmField
val AIR_BALLOON = heldItem("air_balloon")
@JvmField
val AMULET_COIN = heldItem("amulet_coin")
@JvmField
val BINDING_BAND = heldItem("binding_band")
@JvmField
val BLUNDER_POLICY = heldItem("blunder_policy")
@JvmField
val CELL_BATTERY = heldItem("cell_battery")
@JvmField
val CLEAR_AMULET = heldItem("clear_amulet")
@JvmField
val COVERT_CLOAK = heldItem("covert_cloak")
@JvmField
val EJECT_BUTTON = heldItem("eject_button")
@JvmField
val EJECT_PACK = heldItem("eject_pack")
@JvmField
val EXPERT_BELT = heldItem("expert_belt")
@JvmField
val FLAME_ORB = heldItem("flame_orb")
@JvmField
val FOCUS_SASH = heldItem("focus_sash")
@JvmField
val LAGGING_TAIL = heldItem("lagging_tail")
@JvmField
val LIFE_ORB = heldItem("life_orb")
@JvmField
val LOADED_DICE = heldItem("loaded_dice")
@JvmField
val LUMINOUS_MOSS = heldItem("luminous_moss")
@JvmField
val METRONOME = heldItem("metronome")
@JvmField
val PROTECTIVE_PADS = heldItem("protective_pads")
@JvmField
val PUNCHING_GLOVE = heldItem("punching_glove")
@JvmField
val RED_CARD = heldItem("red_card")
@JvmField
val RING_TARGET = heldItem("ring_target")
@JvmField
val ROOM_SERVICE = heldItem("room_service")
@JvmField
val SCOPE_LENS = heldItem("scope_lens")
@JvmField
val SHELL_BELL = heldItem("shell_bell")
@JvmField
val SOOTHE_BELL = heldItem("soothe_bell")
@JvmField
val TERRAIN_EXTRUDER = heldItem("terrain_extruder")
@JvmField
val THROAT_SPRAY = heldItem("throat_spray")
@JvmField
val TOXIC_ORB = heldItem("toxic_orb")
@JvmField
val UTILITY_UMBRELLA = heldItem("utility_umbrella")
@JvmField
val WEAKNESS_POLICY = heldItem("weakness_policy")
@JvmField
val WIDE_LENS = heldItem("wide_lens")
@JvmField
val ZOOM_LENS = heldItem("zoom_lens")
@JvmField
val IRON_BALL = heldItem("iron_ball")
@JvmField
val SMOKE_BALL = heldItem("smoke_ball")
@JvmField
val HEAT_ROCK = heldItem("heat_rock")
@JvmField
val DAMP_ROCK = heldItem("damp_rock")
@JvmField
val SMOOTH_ROCK = heldItem("smooth_rock")
@JvmField
val ICY_ROCK = heldItem("icy_rock")
// Mulch
@JvmField
@@ -717,16 +828,16 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<It
return item
}
private fun apricronItem(name: String, apricornItem: ApricornItem): ApricornItem {
private fun apricornItem(name: String, apricornItem: ApricornItem): ApricornItem {
val finalName = "${name}_apricorn"
val item = this.create(finalName, apricornItem)
compostable(item, .65f)
return item
}
private fun apricronSeedItem(name: String, apricronSeedItem: ApricornSeedItem): ApricornSeedItem {
private fun apricornSeedItem(name: String, apricornSeedItem: ApricornSeedItem): ApricornSeedItem {
val finalName = "${name}_apricorn_seed"
val item = this.create(finalName, apricronSeedItem)
val item = this.create(finalName, apricornSeedItem)
compostable(item, .65f)
return item
}
@@ -11,8 +11,27 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
import com.cobblemon.mod.common.client.net.battle.*
import com.cobblemon.mod.common.client.net.battle.BattleApplyPassResponseHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureEndHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureShakeHandler
import com.cobblemon.mod.common.client.net.battle.BattleCaptureStartHandler
import com.cobblemon.mod.common.client.net.battle.BattleChallengeExpiredHandler
import com.cobblemon.mod.common.client.net.battle.BattleChallengeNotificationHandler
import com.cobblemon.mod.common.client.net.battle.BattleEndHandler
import com.cobblemon.mod.common.client.net.battle.BattleFaintHandler
import com.cobblemon.mod.common.client.net.battle.BattleHealthChangeHandler
import com.cobblemon.mod.common.client.net.battle.BattleInitializeHandler
import com.cobblemon.mod.common.client.net.battle.BattleMadeInvalidChoiceHandler
import com.cobblemon.mod.common.client.net.battle.BattleMakeChoiceHandler
import com.cobblemon.mod.common.client.net.battle.BattleMessageHandler
import com.cobblemon.mod.common.client.net.battle.BattleMusicHandler
import com.cobblemon.mod.common.client.net.battle.BattlePersistentStatusHandler
import com.cobblemon.mod.common.client.net.battle.BattleQueueRequestHandler
import com.cobblemon.mod.common.client.net.battle.BattleSetTeamPokemonHandler
import com.cobblemon.mod.common.client.net.battle.BattleSwitchPokemonHandler
import com.cobblemon.mod.common.client.net.battle.BattleUpdateTeamPokemonHandler
import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
@@ -51,6 +70,7 @@ import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.client.battle.*
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
@@ -99,12 +119,10 @@ import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
import com.cobblemon.mod.common.net.messages.server.*
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectedPacket
import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonSelectedPacket
@@ -134,7 +152,10 @@ import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptanceP
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectedHandler
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSelectedHandler
@@ -168,12 +189,12 @@ import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHa
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
import com.cobblemon.mod.common.util.server
import kotlin.reflect.KClass
import net.minecraft.network.PacketByteBuf
import net.minecraft.network.listener.ClientPlayPacketListener
import net.minecraft.network.packet.Packet
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Identifier
import kotlin.reflect.KClass
/**
* Registers Cobblemon network packets.
@@ -238,6 +259,7 @@ object CobblemonNetwork : NetworkManager {
// UI Packets
this.createClientBound(SummaryUIPacket.ID, SummaryUIPacket::decode, SummaryUIPacketHandler)
this.createClientBound(InteractPokemonUIPacket.ID, InteractPokemonUIPacket::decode, InteractPokemonUIPacketHandler)
this.createClientBound(PlayerInteractOptionsPacket.ID, PlayerInteractOptionsPacket::decode, PlayerInteractOptionsHandler)
// Starter packets
this.createClientBound(OpenStarterUIPacket.ID, OpenStarterUIPacket::decode, StarterUIPacketHandler)
@@ -323,6 +345,7 @@ object CobblemonNetwork : NetworkManager {
// Interaction Packets
this.createServerBound(InteractPokemonPacket.ID, InteractPokemonPacket::decode, InteractPokemonHandler)
this.createServerBound(RequestPlayerInteractionsPacket.ID, RequestPlayerInteractionsPacket::decode, RequestInteractionsHandler)
// Storage Packets
this.createServerBound(SendOutPokemonPacket.ID, SendOutPokemonPacket::decode, SendOutPokemonHandler)
@@ -350,6 +373,8 @@ object CobblemonNetwork : NetworkManager {
// Battle packets
this.createServerBound(BattleSelectActionsPacket.ID, BattleSelectActionsPacket::decode, BattleSelectActionsHandler)
this.createServerBound(SpectateBattlePacket.ID, SpectateBattlePacket::decode, SpectateBattleHandler)
this.createServerBound(RemoveSpectatorPacket.ID, RemoveSpectatorPacket::decode, RemoveSpectatorHandler)
// Trade
this.createServerBound(AcceptTradeRequestPacket.ID, AcceptTradeRequestPacket::decode, AcceptTradeRequestHandler)
@@ -40,6 +40,7 @@ import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMusicPacket
import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.requirements.DefeatRequirement
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.getPlayer
@@ -55,6 +56,7 @@ import net.minecraft.text.Text
* @since January 16th, 2022
* @author Deltric, Hiroku
*/
@Suppress("unused", "MemberVisibilityCanBePrivate")
open class PokemonBattle(
val format: BattleFormat,
val side1: BattleSide,
@@ -68,7 +70,9 @@ open class PokemonBattle(
side2.battle = this
this.actors.forEach { actor ->
actor.pokemonList.forEach { battlePokemon ->
battlePokemon.criticalHits = 0
battlePokemon.effectedPokemon.evolutionProxy.current().progress()
.filterIsInstance<LastBattleCriticalHitsEvolutionProgress>()
.forEach { it.reset() }
}
}
}
@@ -82,12 +86,13 @@ open class PokemonBattle(
val playerUUIDs: Iterable<UUID>
get() = actors.flatMap { it.getPlayerUUIDs() }
val players = playerUUIDs.mapNotNull { it.getPlayer() }
val spectators = mutableListOf<UUID>()
val spectators = mutableSetOf<UUID>()
val battleId = UUID.randomUUID()
val showdownMessages = mutableListOf<String>()
val battleLog = mutableListOf<String>()
val chatLog = mutableListOf<Text>()
var started = false
var ended = false
// TEMP battle showcase stuff
@@ -175,11 +180,8 @@ open class PokemonBattle(
}
fun broadcastChatMessage(component: Text) {
spectators.forEach { spectatorId ->
spectatorId.getPlayer()?.let {
CobblemonNetwork.sendPacketToPlayer(it, BattleMessagePacket(component))
}
}
chatLog.add(component)
sendSpectatorUpdate(BattleMessagePacket(component))
return actors.forEach { it.sendMessage(component) }
}
@@ -66,7 +66,15 @@ interface PokemonSelectingItem {
return if (entity != null) {
val pokemon = entity.pokemon
if (entity.ownerUuid == player.uuid) {
applyToPokemon(player, stack, pokemon) ?: TypedActionResult.pass(stack)
val typedActionResult = applyToPokemon(player, stack, pokemon)
if (typedActionResult != null)
{
CobblemonCriteria.POKEMON_INTERACT.trigger(player, PokemonInteractContext(pokemon.species.resourceIdentifier, Registries.ITEM.getId(stack.item)))
typedActionResult
}
else {
TypedActionResult.pass(stack)
}
} else {
TypedActionResult.fail(stack)
}
@@ -8,14 +8,16 @@
package com.cobblemon.mod.common.api.pokemon.evolution.progress
import com.cobblemon.mod.common.pokemon.evolution.progress.RecoilEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.UseMoveEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.*
object EvolutionProgressFactory {
private val variants = hashMapOf<String, () -> EvolutionProgress<*>>()
init {
registerVariant(DamageTakenEvolutionProgress.ID.toString()) { DamageTakenEvolutionProgress() }
registerVariant(DefeatEvolutionProgress.ID.toString()) { DefeatEvolutionProgress() }
registerVariant(LastBattleCriticalHitsEvolutionProgress.ID.toString()) { LastBattleCriticalHitsEvolutionProgress() }
registerVariant(RecoilEvolutionProgress.ID.toString()) { RecoilEvolutionProgress() }
registerVariant(UseMoveEvolutionProgress.ID.toString()) { UseMoveEvolutionProgress() }
}
@@ -79,6 +79,16 @@ interface HeldItemManager {
*/
fun take(pokemon: BattlePokemon, showdownId: String)
/**
* Tests if the given [BattlePokemon] should have their item consumed.
* This method is expected to be used in each implementation when needed.
*
* @param pokemon The [BattlePokemon] being tested.
* @param battle The [PokemonBattle] the [pokemon] is participating in.
* @param showdownId The literal ID of the held item on Showdown.
*/
fun shouldConsumeItem(pokemon: BattlePokemon, battle: PokemonBattle, showdownId: String): Boolean = false
companion object {
/**
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.pokemon.status
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
import com.cobblemon.mod.common.pokemon.status.statuses.BurnStatus
import com.cobblemon.mod.common.pokemon.status.statuses.FrozenStatus
import com.cobblemon.mod.common.pokemon.status.statuses.ParalysisStatus
@@ -39,4 +40,5 @@ object Statuses {
fun getStatus(name: Identifier) = allStatuses.find { status -> status.name == name }
fun getStatus(showdownName: String) = allStatuses.find { it.showdownName == showdownName }
fun getPersistentStatuses() = allStatuses.filterIsInstance<PersistentStatus>()
}
@@ -31,12 +31,16 @@ open class SpawnerManager {
open fun registerSpawner(spawner: Spawner) {
spawners.add(spawner)
spawner.influences.addAll(influences)
if (spawner !is TickingSpawner) {
spawner.influences.addAll(influences)
}
}
open fun unregisterSpawner(spawner: Spawner) {
spawners.remove(spawner)
spawner.influences.removeAll(influences)
if (spawner !is TickingSpawner) {
spawner.influences.removeAll(influences)
}
}
open fun onServerStarted() {
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.api.spawning.detail.SpawnAction
import com.cobblemon.mod.common.api.spawning.detail.SpawnDetail
import com.cobblemon.mod.common.api.spawning.detail.SpawnPool
import com.cobblemon.mod.common.api.spawning.influence.SpawningInfluence
import com.cobblemon.mod.common.api.spawning.selection.FlatSelector
import com.cobblemon.mod.common.api.spawning.selection.FlatContextWeightedSelector
import com.cobblemon.mod.common.api.spawning.selection.SpawningSelector
import net.minecraft.entity.Entity
@@ -32,7 +32,7 @@ abstract class TickingSpawner(
var spawns: SpawnPool,
val manager: SpawnerManager
) : Spawner {
private var selector: SpawningSelector = FlatSelector()
private var selector: SpawningSelector = FlatContextWeightedSelector()
override val influences = mutableListOf<SpawningInfluence>()
override fun canSpawn() = active
@@ -22,6 +22,8 @@ import net.minecraft.registry.tag.TagKey
@Suppress("HasPlatformType", "unused")
object CobblemonBlockTags {
@JvmField val ALL_HANGING_SIGNS = createTag("all_hanging_signs")
@JvmField val ALL_SIGNS = createTag("all_signs")
@JvmField val APRICORN_LEAVES = createTag("apricorn_leaves")
@JvmField val APRICORN_LOGS = createTag("apricorn_logs")
@JvmField val APRICORN_SAPLINGS = createTag("apricorn_saplings")
@@ -29,6 +31,7 @@ object CobblemonBlockTags {
@JvmField val BERRY_WILD_SOIL = createTag("berry_wild_soil")
@JvmField val BERRY_SOIL = createTag("berry_soil")
@JvmField val BERRY_REPLACEABLE = createTag("berry_replaceable")
@JvmField val CEILING_HANGING_SIGNS = createTag("ceiling_hanging_signs")
@JvmField val CROPS = createTag("crops")
@JvmField val DRIPSTONE_GROWABLE = createTag("dripstone_growable")
@JvmField val DRIPSTONE_REPLACEABLES = createTag("dripstone_replaceables")
@@ -36,10 +39,15 @@ object CobblemonBlockTags {
@JvmField val MEDICINAL_LEEK_PLANTABLE = createTag("medicinal_leek_plantable")
@JvmField val MINTS = createTag("mints")
@JvmField val ROOTS_SPREADABLE = createTag("roots_spreadable")
@JvmField val SIGNS = createTag("signs")
@JvmField val SMALL_FLOWERS = createTag("small_flowers")
@JvmField val SEES_SKY = createTag("sees_sky")
@JvmField val SNOW_BLOCK = createTag("snow_block")
@JvmField val ROOTS = createTag("roots")
@JvmField val STANDING_SIGNS = createTag("standing_signs")
@JvmField val WALL_HANGING_SIGNS = createTag("wall_hanging_signs")
@JvmField val WALL_SIGNS = createTag("wall_signs")
private fun createTag(name: String) = TagKey.of(RegistryKeys.BLOCK, cobblemonResource(name))
}
@@ -9,15 +9,17 @@
package com.cobblemon.mod.common.api.tags
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.tag.TagKey
/**
* A collection of the Cobblemon [TagKey]s related to the [Registry.ENTITY_TYPE].
* A collection of the Cobblemon [TagKey]s related to the [Registries.ENTITY_TYPE].
*
* @author Licious
* @since March 6th, 2023
*/
@Suppress("HasPlatformType", "unused")
object CobblemonEntityTypeTags {
@@ -27,6 +29,9 @@ object CobblemonEntityTypeTags {
@JvmField
val CANNOT_HAVE_NAME_TAG = create("cannot_have_name_tag")
@JvmField
val BOATS = create("boats")
private fun create(path: String) = TagKey.of(RegistryKeys.ENTITY_TYPE, cobblemonResource(path))
}
@@ -9,16 +9,17 @@
package com.cobblemon.mod.common.api.tags
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.registry.Registry
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.tag.TagKey
/**
* A collection of the Cobblemon [TagKey]s related to the [Registry.ITEM].
* A collection of the Cobblemon [TagKey]s related to the [Registries.ITEM].
*
* @author Licious
* @since January 8th, 2023
*/
@Suppress("unused", "HasPlatformType")
object CobblemonItemTags {
@JvmField
@@ -27,11 +28,47 @@ object CobblemonItemTags {
val APRICORN_SEEDS = create("apricorn_seeds")
@JvmField
val APRICORNS = create("apricorns")
/**
* This tag is only used for a Torterra aspect based easter egg evolution at the moment.
* It simply includes the 'minecraft:azalea' and 'minecraft:flowering_azalea' items by default.
*/
@JvmField
val AZALEA_TREE = create("azalea_tree")
@JvmField
val BERRIES = create("berries")
@JvmField
val BOATS = create("boats")
@JvmField
val COBBLEMON_SEEDS = create("cobblemon_seeds")
@JvmField
val EVOLUTION_ITEMS = create("evolution_items")
@JvmField
val EVOLUTION_STONES = create("evolution_stones")
@JvmField
val EXPERIENCE_CANDIES = create("experience_candies")
@JvmField
val HANGING_SIGNS = create("hanging_signs")
@JvmField
val HERBS = create("herbs")
@JvmField
val MINT_LEAF = create("mint_leaf")
@JvmField
val MINTS = create("mints")
@JvmField
val MUTATED_BERRIES = create("mutated_berries")
@JvmField
val PLANTS = create("plants")
@JvmField
val POKEBALLS = create("poke_balls")
@JvmField
val PROTEIN_INGREDIENTS = create("protein_ingredients")
@JvmField
val SEEDS = create("seeds")
@JvmField
val SIGNS = create("signs")
@JvmField
val ZINC_INGREDIENTS = create("zinc_ingredients")
@JvmField
val ANY_HELD_ITEM = create("held/is_held_item")
@JvmField
val EXPERIENCE_SHARE = create("held/experience_share")
@@ -54,19 +91,11 @@ object CobblemonItemTags {
@JvmField
val POWER_WEIGHT = create("held/power_weight")
@JvmField
val EVOLUTION_STONES = create("evolution_stones")
val CONSUMED_IN_NPC_BATTLE = create("held/consumed_in_npc_battle")
@JvmField
val EVOLUTION_ITEMS = create("evolution_items")
val CONSUMED_IN_PVP_BATTLE = create("held/consumed_in_pvp_battle")
@JvmField
val MINTS = create("mints")
@JvmField
val MINT_LEAVES = create("mint_leaves")
/**
* This tag is only used for a Torterra aspect based easter egg evolution at the moment.
* It simply includes the 'minecraft:azalea' and 'minecraft:flowering_azalea' items by default.
*/
val AZALEA_TREE = create("azalea_tree")
val CONSUMED_IN_WILD_BATTLE = create("held/consumed_in_wild_battle")
private fun create(path: String) = TagKey.of(RegistryKeys.ITEM, cobblemonResource(path))
@@ -221,6 +221,10 @@ object BattleRegistry {
return battleMap.values.find { it.getActor(serverPlayerEntity) != null }
}
fun getBattleByParticipatingPlayerId(playerId: UUID): PokemonBattle? {
return battleMap.values.find { playerId in it.playerUUIDs }
}
fun tick() {
battleMap.forEachValue(Long.MAX_VALUE) { it.tick() }
}
@@ -206,7 +206,7 @@ data class SwitchActionResponse(var newPokemonId: UUID) : ShowdownActionResponse
val pokemon = activeBattlePokemon.actor.pokemonList.find { it.uuid == newPokemonId }
return when {
pokemon == null -> false // No such Pokémon
pokemon.health <= 0 -> false // Pokémon is dead
(!activeBattlePokemon.actor.request?.side?.pokemon?.get(0)?.reviving!! && pokemon.health <= 0) -> false // Checks if the active Pokémon is reviving, if so ignore this check. If not, return false if dead
showdownMoveSet != null && showdownMoveSet.trapped -> false // You're not allowed to switch
activeBattlePokemon.actor.getSide().activePokemon.any { it.battlePokemon?.uuid == newPokemonId } -> false // Pokémon is already sent out
else -> true
@@ -35,6 +35,7 @@ import com.cobblemon.mod.common.battles.interpreter.ContextManager
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.net.messages.client.battle.*
import com.cobblemon.mod.common.pokemon.evolution.progress.DamageTakenEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.RecoilEvolutionProgress
import com.cobblemon.mod.common.pokemon.evolution.progress.UseMoveEvolutionProgress
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
@@ -47,6 +48,7 @@ import net.minecraft.server.world.ServerWorld
import net.minecraft.text.MutableText
import net.minecraft.text.Text
@Suppress("KotlinPlaceholderCountMatchesArgumentCount", "UNUSED_PARAMETER")
object ShowdownInterpreter {
private val updateInstructions = mutableMapOf<String, (PokemonBattle, BattleMessage, MutableList<String>) -> Unit>()
private val sideUpdateInstructions = mutableMapOf<String, (PokemonBattle, BattleActor, BattleMessage) -> Unit>()
@@ -81,6 +83,7 @@ object ShowdownInterpreter {
updateInstructions["|-mustrecharge|"] = this::handleRechargeInstructions
updateInstructions["|-fail|"] = this::handleFailInstruction
updateInstructions["|-start|"] = this::handleStartInstructions
updateInstructions["|-block|"] = this::handleBlockInstructions
updateInstructions["|-activate|"] = this::handleActivateInstructions
updateInstructions["|-curestatus|"] = this::handleCureStatusInstruction
updateInstructions["|-fieldstart|"] = this::handleFieldStartInstructions
@@ -779,7 +782,10 @@ object ShowdownInterpreter {
battle.broadcastChatMessage(battleLang("crit").yellow())
this.lastCauser[battle.battleId]?.let { message ->
val battlePokemon = message.getBattlePokemon(0, battle) ?: return@let
battlePokemon.criticalHits++
if (LastBattleCriticalHitsEvolutionProgress.supports(battlePokemon.effectedPokemon)) {
val progress = battlePokemon.effectedPokemon.evolutionProxy.current().progressFirstOrCreate({ it is LastBattleCriticalHitsEvolutionProgress }) { LastBattleCriticalHitsEvolutionProgress() }
progress.updateProgress(LastBattleCriticalHitsEvolutionProgress.Progress(progress.currentProgress().amount + 1))
}
}
battle.minorBattleActions[pokemon.uuid] = message
}
@@ -822,10 +828,19 @@ object ShowdownInterpreter {
*
* The specified ACTION has failed against the POKEMON targetted.
*/
private fun handleFailInstruction(battle: PokemonBattle, message: BattleMessage, remainingLines: MutableList<String>){
private fun handleFailInstruction(battle: PokemonBattle, message: BattleMessage, remainingLines: MutableList<String>) {
battle.dispatchWaiting(1.5F){
val pokemon = message.getBattlePokemon(0, battle) ?: return@dispatchWaiting
battle.broadcastChatMessage(battleLang("fail").red())
val pokemonName = pokemon.getName()
val effectID = message.effectAt(1)?.id ?: return@dispatchWaiting
val lang = when (effectID) {
"shedtail" -> battleLang("fail.substitute", pokemonName)
"hyperspacefury" -> battleLang("fail.darkvoid", pokemonName)
"corrosivegas" -> battleLang("fail.healblock", pokemonName)
else -> battleLang("fail.$effectID", pokemonName)
}
battle.broadcastChatMessage(lang.red())
battle.minorBattleActions[pokemon.uuid] = message
}
}
@@ -902,6 +917,7 @@ object ShowdownInterpreter {
"perish2", "perish1", "perish0" -> battleLang("start.perish", pokemon.getName(), effectID.last().digitToInt())
"dynamax" -> battleLang("start.${message.effectAt(2)?.id ?: effectID}", pokemon.getName()).yellow()
"curse" -> battleLang("start.curse", message.getSourceBattlePokemon(battle)!!.getName(), pokemon.getName())
"disable" -> battleLang("start.disable", pokemon.getName(), message.effectAt(2)!!.rawData)
else -> battleLang("start.$effectID", pokemon.getName())
}
battle.broadcastChatMessage(lang)
@@ -945,6 +961,27 @@ object ShowdownInterpreter {
}
}
/**
* Format:
* |-block|POKEMON|EFFECT|MOVE|ATTACKER
*
* An effect targeted at POKEMON was blocked by EFFECT. This may optionally specify that the effect was a MOVE from ATTACKER. [of]SOURCE will note the owner of the EFFECT, in the case that it's not EFFECT (for instance, an ally with Aroma Veil.)
*/
private fun handleBlockInstructions(battle: PokemonBattle, message: BattleMessage, remainingLines: MutableList<String>) {
battle.dispatchWaiting(1.5F) {
val pokemon = message.getBattlePokemon(0, battle) ?: return@dispatchWaiting
val pokemonName = pokemon.getName()
val effectID = message.effectAt(1)?.id ?: return@dispatchWaiting
val lang = when (effectID) {
"matblock" -> battleLang("block.matblock", message.effectAt(2)!!.rawData)
else -> battleLang("block.$effectID", pokemonName)
}
battle.broadcastChatMessage(lang)
battle.minorBattleActions[pokemon.uuid] = message
}
}
/**
* Format:
* |-activate|POKEMON|EFFECT
@@ -969,6 +1006,7 @@ object ShowdownInterpreter {
"spite" -> battleLang("activate.spite", pokemonName, message.argumentAt(2)!!, message.argumentAt(3)!!)
// Don't need additional lang, announced elsewhere
"toxicdebris", "shedskin" -> return@dispatch GO
"matblock" -> battleLang("activate.matblock", message.effectAt(2)!!.rawData)
// Add activation to each Pokemon's history
"destinybond" -> {
battle.activePokemon.mapNotNull { it.battlePokemon?.uuid }.forEach { battle.minorBattleActions[it] = message }
@@ -981,6 +1019,7 @@ object ShowdownInterpreter {
}
"focussash", "focusband" -> battleLang("activate.focusband", pokemonName, message.effectAt(1)!!.typelessData)
"maxguard", "protect" -> battleLang("activate.protect", pokemonName)
"shadowforce", "hyperspacefury", "hyperspacehole" -> battleLang("activate.phantomforce", pokemonName)
else -> battleLang("activate.${effect.id}", pokemonName, sourceName)
}
battle.broadcastChatMessage(lang)
@@ -1047,7 +1086,7 @@ object ShowdownInterpreter {
/**
* Format:
* |-ability|POKEMON|ABILITY|[from]EFFECT
* |-ability|POKEMON|ABILITY|&#91from&#93EFFECT
*
* The ABILITY of the POKEMON has been changed due to a move/ability EFFECT.
*
@@ -1115,6 +1154,8 @@ object ShowdownInterpreter {
}
}
/**
* Format:
* |-swapboost|SOURCE|TARGET|STATS
@@ -1412,6 +1453,8 @@ object ShowdownInterpreter {
lang("status.$status.hurt", pokemonName)
}
"aftermath" -> battleLang("damage.generic", pokemonName)
"chloroblast", "steelbeam" -> battleLang("damage.mindblown", pokemonName)
"jumpkick" -> battleLang("damage.highjumpkick", pokemonName)
else -> battleLang("damage.${effect.id}", pokemonName, sourceName)
}
battle.broadcastChatMessage(lang.red())
@@ -1442,7 +1485,9 @@ object ShowdownInterpreter {
GO
}
}
privateMessage.pnxAndUuid(0)?.let { (pnx, _) -> battle.sendSidedUpdate(actor, BattleHealthChangePacket(pnx, remainingHealth.toFloat()), BattleHealthChangePacket(pnx, newHealthRatio)) }
privateMessage.pnxAndUuid(0)?.let { (pnx, _) -> {
battle.sendSidedUpdate(actor, BattleHealthChangePacket(pnx, remainingHealth.toFloat()), BattleHealthChangePacket(pnx, newHealthRatio))
}}
battle.minorBattleActions[battlePokemon.uuid] = privateMessage
WaitDispatch(1F)
@@ -1502,7 +1547,7 @@ object ShowdownInterpreter {
/**
* Format:
* |-item|POKEMON|ITEM|[from]EFFECT
* |-item|POKEMON|ITEM|&#91from&#93EFFECT
*
* The ITEM held by the POKEMON has been changed or revealed due to a move or ability EFFECT.
*
@@ -1525,7 +1570,7 @@ object ShowdownInterpreter {
/**
* Format:
* |-enditem|POKEMON|ITEM|[from]EFFECT
* |-enditem|POKEMON|ITEM|&#91from&#93EFFECT
*
* The ITEM held by POKEMON has been destroyed by a move or ability, and it now holds no item.
*
@@ -1559,7 +1604,7 @@ object ShowdownInterpreter {
val rawHpAndStatus = privateMessage.argumentAt(1)?.split(" ") ?: return
val rawHpRatio = rawHpAndStatus.getOrNull(0) ?: return
val newHealth = rawHpRatio.split("/").map { it.toFloatOrNull() ?: return }
val newHealthRatio = rawHpRatio.split("/").map { it.toFloatOrNull()?.div(100) ?: return }
val newHealthRatio = rawHpRatio.split("/").map { it.toFloatOrNull()?.div(newHealth[1]) ?: return }
val effect = privateMessage.effect()
val pokemonName = battlePokemon.getName()
broadcastOptionalAbility(battle, effect, pokemonName)
@@ -64,11 +64,6 @@ open class BattlePokemon(
/** A set of all the BattlePokemon that they faced during the battle (for exp purposes) */
val facedOpponents = mutableSetOf<BattlePokemon>()
/**
* A counter of critical hits during this battle, this is used for an evolution requirement.
*/
var criticalHits: Int = 0
/**
* The [HeldItemManager] backing this [BattlePokemon].
*/
@@ -89,7 +84,12 @@ open class BattlePokemon(
}
fun isSentOut() = actor.battle.activePokemon.any { it.battlePokemon == this }
fun canBeSentOut() = !isSentOut() && !willBeSwitchedIn && health > 0
fun canBeSentOut() =
if (actor.request?.side?.pokemon?.get(0)?.reviving == true) {
!isSentOut() && !willBeSwitchedIn && health <= 0
} else {
!isSentOut() && !willBeSwitchedIn && health > 0
}
fun writeVariables(struct: VariableStruct) {
effectedPokemon.writeVariables(struct)
@@ -0,0 +1,21 @@
/*
* 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.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import net.minecraft.block.BlockState
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.block.entity.HangingSignBlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonHangingSignBlockEntity(pos: BlockPos, state: BlockState) : HangingSignBlockEntity(pos, state) {
override fun getType(): BlockEntityType<*> = CobblemonBlockEntities.HANGING_SIGN
}
@@ -0,0 +1,21 @@
/*
* 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.block.entity
import com.cobblemon.mod.common.CobblemonBlockEntities
import net.minecraft.block.BlockState
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.block.entity.SignBlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonSignBlockEntity(pos: BlockPos, state: BlockState) : SignBlockEntity(pos, state) {
override fun getType(): BlockEntityType<*> = CobblemonBlockEntities.SIGN
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonHangingSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.HangingSignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonHangingSignBlock(settings: Settings, woodType: WoodType) : HangingSignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonHangingSignBlockEntity(pos, state)
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.SignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonSignBlock(settings: Settings, woodType: WoodType) : SignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonHangingSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.WallHangingSignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonWallHangingSignBlock(settings: Settings, woodType: WoodType) : WallHangingSignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonHangingSignBlockEntity(pos, state)
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.block.sign
import com.cobblemon.mod.common.block.entity.CobblemonSignBlockEntity
import net.minecraft.block.BlockState
import net.minecraft.block.WallSignBlock
import net.minecraft.block.WoodType
import net.minecraft.block.entity.BlockEntity
import net.minecraft.util.math.BlockPos
class CobblemonWallSignBlock(settings: Settings, woodType: WoodType) : WallSignBlock(settings, woodType) {
override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity = CobblemonSignBlockEntity(pos, state)
}
@@ -9,74 +9,47 @@
package com.cobblemon.mod.common.brewing
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.brewing.ingredient.CobblemonIngredient
import com.cobblemon.mod.common.brewing.ingredient.CobblemonItemIngredient
import com.cobblemon.mod.common.brewing.ingredient.CobblemonPotionIngredient
import net.minecraft.item.Item
import net.minecraft.potion.Potion
import net.minecraft.potion.Potions
import net.minecraft.recipe.BrewingRecipeRegistry
import net.minecraft.recipe.Ingredient
object BrewingRecipes {
// Put things here if you want them to be add-able to the bottom of the brewing stand (like where potions go)
@JvmField
val brewableItems = mutableListOf(
CobblemonItems.MEDICINAL_BREW,
CobblemonItems.POTION,
CobblemonItems.SUPER_POTION,
CobblemonItems.HYPER_POTION,
CobblemonItems.MAX_POTION,
CobblemonItems.FULL_RESTORE,
CobblemonItems.FULL_HEAL,
CobblemonItems.ANTIDOTE,
CobblemonItems.AWAKENING,
CobblemonItems.BURN_HEAL,
CobblemonItems.ICE_HEAL,
CobblemonItems.PARALYZE_HEAL,
CobblemonItems.ETHER,
CobblemonItems.MAX_ETHER,
CobblemonItems.ELIXIR,
CobblemonItems.MAX_ELIXIR
)
fun registerPotionTypes() {
brewableItems.forEach { item ->
BrewingRecipeRegistry.POTION_TYPES.add(Ingredient.ofItems(item))
}
}
fun getPotionRecipes(): List<Triple<Potion, Ingredient, Potion>> {
return listOf(
Triple(Potions.WATER, Ingredient.ofItems(CobblemonItems.MEDICINAL_LEEK), Potions.WATER), // This one is Mixin'd to result in brew rather than water
val recipes: List<Triple<CobblemonIngredient, CobblemonIngredient, Item>> by lazy {
listOf(
Triple(CobblemonPotionIngredient(Potions.WATER), CobblemonItemIngredient(CobblemonItems.MEDICINAL_LEEK), CobblemonItems.MEDICINAL_BREW),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.LEPPA_BERRY, CobblemonItems.ETHER),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.HOPO_BERRY, CobblemonItems.ELIXIR),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.ORAN_BERRY, CobblemonItems.POTION),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.SITRUS_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.PECHA_BERRY, CobblemonItems.ANTIDOTE),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.CHESTO_BERRY, CobblemonItems.AWAKENING),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.RAWST_BERRY, CobblemonItems.BURN_HEAL),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.ASPEAR_BERRY, CobblemonItems.ICE_HEAL),
convert(CobblemonItems.MEDICINAL_BREW, CobblemonItems.CHERI_BERRY, CobblemonItems.PARALYZE_HEAL),
convert(CobblemonItems.BURN_HEAL, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.ANTIDOTE, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.AWAKENING, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.ICE_HEAL, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.PARALYZE_HEAL, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_HEAL),
convert(CobblemonItems.ETHER, CobblemonItems.PEP_UP_FLOWER, CobblemonItems.MAX_ETHER),
convert(CobblemonItems.ELIXIR, CobblemonItems.PEP_UP_FLOWER, CobblemonItems.MAX_ELIXIR),
convert(CobblemonItems.POTION, CobblemonItems.ENERGY_ROOT, CobblemonItems.SUPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.FIGY_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.WIKI_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.MAGO_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.AGUAV_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.SUPER_POTION, CobblemonItems.IAPAPA_BERRY, CobblemonItems.HYPER_POTION),
convert(CobblemonItems.HYPER_POTION, CobblemonItems.VIVICHOKE, CobblemonItems.MAX_POTION),
convert(CobblemonItems.MAX_POTION, CobblemonItems.LUM_BERRY, CobblemonItems.FULL_RESTORE)
)
}
fun getItemRecipes(): List<Triple<Item, Ingredient, Item>> {
// This is where the majority of our recipes go. First arg is thing down the bottom, second is thing up the top, third is results.
return listOf(
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.LEPPA_BERRY), CobblemonItems.ETHER),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.HOPO_BERRY), CobblemonItems.ELIXIR),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.ORAN_BERRY), CobblemonItems.POTION),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.SITRUS_BERRY), CobblemonItems.HYPER_POTION),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_HEAL),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.PECHA_BERRY), CobblemonItems.ANTIDOTE),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.CHESTO_BERRY), CobblemonItems.AWAKENING),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.RAWST_BERRY), CobblemonItems.BURN_HEAL),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.ASPEAR_BERRY), CobblemonItems.ICE_HEAL),
Triple(CobblemonItems.MEDICINAL_BREW, Ingredient.ofItems(CobblemonItems.CHERI_BERRY), CobblemonItems.PARALYZE_HEAL),
Triple(CobblemonItems.BURN_HEAL, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_HEAL),
Triple(CobblemonItems.ANTIDOTE, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_HEAL),
Triple(CobblemonItems.AWAKENING, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_HEAL),
Triple(CobblemonItems.ICE_HEAL, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_HEAL),
Triple(CobblemonItems.PARALYZE_HEAL, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_HEAL),
Triple(CobblemonItems.ETHER, Ingredient.ofItems(CobblemonItems.PEP_UP_FLOWER), CobblemonItems.MAX_ETHER),
Triple(CobblemonItems.ELIXIR, Ingredient.ofItems(CobblemonItems.PEP_UP_FLOWER), CobblemonItems.MAX_ELIXIR),
Triple(CobblemonItems.POTION, Ingredient.ofItems(CobblemonItems.ENERGY_ROOT), CobblemonItems.SUPER_POTION),
Triple(CobblemonItems.SUPER_POTION, Ingredient.ofItems(CobblemonItems.FIGY_BERRY), CobblemonItems.HYPER_POTION),
Triple(CobblemonItems.SUPER_POTION, Ingredient.ofItems(CobblemonItems.WIKI_BERRY), CobblemonItems.HYPER_POTION),
Triple(CobblemonItems.SUPER_POTION, Ingredient.ofItems(CobblemonItems.MAGO_BERRY), CobblemonItems.HYPER_POTION),
Triple(CobblemonItems.SUPER_POTION, Ingredient.ofItems(CobblemonItems.AGUAV_BERRY), CobblemonItems.HYPER_POTION),
Triple(CobblemonItems.SUPER_POTION, Ingredient.ofItems(CobblemonItems.IAPAPA_BERRY), CobblemonItems.HYPER_POTION),
Triple(CobblemonItems.HYPER_POTION, Ingredient.ofItems(CobblemonItems.VIVICHOKE), CobblemonItems.MAX_POTION),
Triple(CobblemonItems.MAX_POTION, Ingredient.ofItems(CobblemonItems.LUM_BERRY), CobblemonItems.FULL_RESTORE)
)
private fun convert(input: Item, ingredient: Item, output: Item): Triple<CobblemonIngredient, CobblemonIngredient, Item> {
return Triple(CobblemonItemIngredient(input), CobblemonItemIngredient(ingredient), output)
}
}
@@ -0,0 +1,36 @@
/*
* 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.brewing.ingredient
import net.minecraft.item.ItemStack
import org.jetbrains.annotations.ApiStatus
/**
* The Cobblemon representation of a brewing ingredient.
* This is done to abstract platform specific requirements for a more custom solution to brewing.
*/
@ApiStatus.Internal
sealed interface CobblemonIngredient {
/**
* Tests if a given [stack] is valid for this ingredient.
*
* @param stack The [ItemStack] being tested.
* @return If the given [stack] is valid for this ingredient.
*/
fun matches(stack: ItemStack): Boolean
/**
* Resolves list of [ItemStack]s that is used by the vanilla Ingredient implementation when a platform requires wrapping.
*
* @return A list of [ItemStack]s
*/
fun matchingStacks(): List<ItemStack>
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.brewing.ingredient
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
class CobblemonItemIngredient(val item: Item) : CobblemonIngredient {
override fun matches(stack: ItemStack): Boolean = stack.isOf(this.item)
override fun matchingStacks(): List<ItemStack> = listOf(this.item.defaultStack)
}
@@ -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.brewing.ingredient
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.potion.Potion
import net.minecraft.potion.PotionUtil
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
class CobblemonPotionIngredient(val potion: Potion) : CobblemonIngredient {
override fun matches(stack: ItemStack): Boolean {
val potion = PotionUtil.getPotion(stack)
return potion == this.potion
}
override fun matchingStacks(): List<ItemStack> {
val list = arrayListOf<ItemStack>()
list += PotionUtil.setPotion(Items.POTION.defaultStack, this.potion)
list += PotionUtil.setPotion(Items.SPLASH_POTION.defaultStack, this.potion)
list += PotionUtil.setPotion(Items.LINGERING_POTION.defaultStack, this.potion)
return list
}
}
@@ -18,10 +18,12 @@ import com.cobblemon.mod.common.client.gui.battle.BattleOverlay
import com.cobblemon.mod.common.client.particle.BedrockParticleEffectRepository
import com.cobblemon.mod.common.client.render.block.BerryBlockRenderer
import com.cobblemon.mod.common.client.render.block.HealingMachineRenderer
import com.cobblemon.mod.common.client.render.boat.CobblemonBoatRenderer
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
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.BerryModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokeBallModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
import com.cobblemon.mod.common.client.render.pokeball.PokeBallRenderer
@@ -30,16 +32,19 @@ import com.cobblemon.mod.common.client.starter.ClientPlayerData
import com.cobblemon.mod.common.client.storage.ClientStorageManager
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.item.PokeBallItem
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
import com.cobblemon.mod.common.platform.events.PlatformEvents
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.asTranslated
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.block.entity.HangingSignBlockEntityRenderer
import net.minecraft.client.render.block.entity.SignBlockEntityRenderer
import net.minecraft.client.render.entity.EntityRenderer
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.LivingEntityRenderer
import net.minecraft.client.render.entity.model.BoatEntityModel
import net.minecraft.client.render.entity.model.ChestBoatEntityModel
import net.minecraft.client.render.entity.model.PlayerEntityModel
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
@@ -83,12 +88,11 @@ object CobblemonClient {
PlatformEvents.CLIENT_PLAYER_LOGIN.subscribe { onLogin() }
PlatformEvents.CLIENT_PLAYER_LOGOUT.subscribe { onLogout() }
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HEALING_MACHINE, ::HealingMachineRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.BERRY, ::BerryBlockRenderer)
this.registerBlockEntityRenderers()
registerBlockRenderTypes()
//registerColors()
registerFlywheelRenderers()
this.registerEntityRenderers()
LOGGER.info("Registering custom BuiltinItemRenderers")
CobblemonBuiltinItemRendererRegistry.register(CobblemonItems.POKEMON_MODEL, PokemonItemRenderer())
@@ -143,6 +147,10 @@ object CobblemonClient {
RenderLayer.getCutout(),
CobblemonBlocks.APRICORN_DOOR,
CobblemonBlocks.APRICORN_TRAPDOOR,
CobblemonBlocks.APRICORN_SIGN,
CobblemonBlocks.APRICORN_WALL_SIGN,
CobblemonBlocks.APRICORN_HANGING_SIGN,
CobblemonBlocks.APRICORN_WALL_HANGING_SIGN,
CobblemonBlocks.BLACK_APRICORN_SAPLING,
CobblemonBlocks.BLUE_APRICORN_SAPLING,
CobblemonBlocks.GREEN_APRICORN_SAPLING,
@@ -176,6 +184,8 @@ object CobblemonClient {
CobblemonBlocks.REVIVAL_HERB,
*CobblemonBlocks.berries().values.toTypedArray()
)
this.createBoatModelLayers()
}
fun beforeChatRender(context: DrawContext, partialDeltaTicks: Float) {
@@ -194,14 +204,22 @@ object CobblemonClient {
renderer?.addFeature(PokemonOnShoulderRenderer(renderer))
}
fun registerPokemonRenderer(context: EntityRendererFactory.Context): PokemonRenderer {
LOGGER.info("Registering Pokémon renderer")
return PokemonRenderer(context)
private fun registerBlockEntityRenderers() {
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HEALING_MACHINE, ::HealingMachineRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.BERRY, ::BerryBlockRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.SIGN, ::SignBlockEntityRenderer)
this.implementation.registerBlockEntityRenderer(CobblemonBlockEntities.HANGING_SIGN, ::HangingSignBlockEntityRenderer)
}
fun registerPokeBallRenderer(context: EntityRendererFactory.Context): PokeBallRenderer {
private fun registerEntityRenderers() {
LOGGER.info("Registering Pokémon renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.POKEMON, ::PokemonRenderer)
LOGGER.info("Registering PokéBall renderer")
return PokeBallRenderer(context)
this.implementation.registerEntityRenderer(CobblemonEntities.EMPTY_POKEBALL, ::PokeBallRenderer)
LOGGER.info("Registering Boat renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.BOAT) { ctx -> CobblemonBoatRenderer(ctx, false) }
LOGGER.info("Registering Boat with Chest renderer")
this.implementation.registerEntityRenderer(CobblemonEntities.CHEST_BOAT) { ctx -> CobblemonBoatRenderer(ctx, true) }
}
fun reloadCodedAssets(resourceManager: ResourceManager) {
@@ -215,7 +233,6 @@ object CobblemonClient {
PokeBallModelRepository.reload(resourceManager)
BerryModelRepository.reload(resourceManager)
LOGGER.info("Loaded assets")
// PokeBallModelRepository.reload(resourceManager)
}
fun endBattle() {
@@ -230,4 +247,11 @@ object CobblemonClient {
return "${stack.translationKey}.tooltip"
}
private fun createBoatModelLayers() {
CobblemonBoatType.values().forEach { type ->
this.implementation.registerLayer(CobblemonBoatRenderer.createBoatModelLayer(type, false), BoatEntityModel::getTexturedModelData)
this.implementation.registerLayer(CobblemonBoatRenderer.createBoatModelLayer(type, true), ChestBoatEntityModel::getTexturedModelData)
}
}
}
@@ -13,12 +13,14 @@ import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.battle.ClientBattleActor
import com.cobblemon.mod.common.client.battle.SingleActionRequest
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleActionSelection
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleBackButton
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleGeneralActionSelection
import com.cobblemon.mod.common.client.gui.battle.subscreen.BattleSwitchPokemonSelection
import com.cobblemon.mod.common.client.gui.battle.widgets.BattleMessagePane
import com.cobblemon.mod.common.client.keybind.boundKey
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import com.cobblemon.mod.common.util.battleLang
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.MinecraftClient
@@ -41,6 +43,7 @@ class BattleGUI : Screen(battleLang("gui.title")) {
private lateinit var messagePane: BattleMessagePane
var opacity = 0F
val actor = CobblemonClient.battle?.side1?.actors?.find { it.uuid == MinecraftClient.getInstance().player?.uuid }
val specBackButton = BattleBackButton(12f, MinecraftClient.getInstance().window.scaledHeight - 32f)
var queuedActions = mutableListOf<() -> Unit>()
@@ -106,6 +109,10 @@ class BattleGUI : Screen(battleLang("gui.title")) {
}
}
if (battle.spectating) {
specBackButton.render(context.matrices, mouseX, mouseY, delta)
}
val currentSelection = getCurrentActionSelection()
if (currentSelection == null || currentSelection is BattleGeneralActionSelection ) {
drawScaledText(
@@ -153,4 +160,13 @@ class BattleGUI : Screen(battleLang("gui.title")) {
}
return super.charTyped(chr, modifiers)
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
val battle = CobblemonClient.battle
if (battle?.spectating == true && specBackButton.isHovered(mouseX, mouseY)) {
RemoveSpectatorPacket(battle.battleId).sendToServer()
CobblemonClient.endBattle()
}
return super.mouseClicked(mouseX, mouseY, button)
}
}
@@ -9,8 +9,7 @@
package com.cobblemon.mod.common.client.gui.battle.subscreen
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.battles.ShowdownPokemon
import com.cobblemon.mod.common.battles.SwitchActionResponse
import com.cobblemon.mod.common.battles.*
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.battle.SingleActionRequest
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
@@ -24,6 +23,7 @@ import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder
import net.minecraft.client.sound.PositionedSoundInstance
import net.minecraft.client.sound.SoundManager
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.math.MathHelper.ceil
class BattleSwitchPokemonSelection(
battleGUI: BattleGUI,
@@ -83,7 +83,6 @@ class BattleSwitchPokemonSelection(
partialTicks = deltaTicks
)
} catch (exception: Exception) {
println(showdownPokemon.condition)
throw exception
}
}
@@ -98,9 +97,15 @@ class BattleSwitchPokemonSelection(
.find { it.uuid == showdownPokemon.uuid }
?.let { showdownPokemon to it }
}
.filter {
if (request.side.pokemon[0].reviving) {
"fnt" in it.first.condition
} else {
"fnt" !in it.first.condition
}
}
.filter { it.second.uuid !in battleGUI.actor!!.activePokemon.map { it.battlePokemon?.uuid } }
.filter { it.second.uuid !in switchingInPokemon }
.filter { "fnt" !in it.first.condition || it.first.reviving }
showdownPokemonToPokemon.forEachIndexed { index, (showdownPokemon, pokemon) ->
val row = index / 2
@@ -10,7 +10,9 @@ package com.cobblemon.mod.common.client.gui.interact.wheel
import com.cobblemon.mod.common.CobblemonNetwork
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
@@ -48,14 +50,14 @@ fun createPokemonInteractGui(pokemonID: UUID, canMountShoulder: Boolean): Intera
return InteractWheelGUI(options, Text.translatable("cobblemon.ui.interact.pokemon"))
}
fun createPlayerInteractGui(targetPlayer: PlayerEntity, pokemon: Pokemon): InteractWheelGUI {
fun createPlayerInteractGui(optionsPacket: PlayerInteractOptionsPacket): InteractWheelGUI {
val trade = InteractWheelOption(
iconResource = cobblemonResource("textures/gui/interact/icon_trade.png"),
colour = { if (CobblemonClient.requests.tradeOffers.any { it.traderId == targetPlayer.uuid }) Vector3f(0F, 0.6F, 0F) else null },
colour = { if (CobblemonClient.requests.tradeOffers.any { it.traderId == optionsPacket.targetId }) Vector3f(0F, 0.6F, 0F) else null },
onPress = {
val tradeOffer = CobblemonClient.requests.tradeOffers.find { it.traderId == targetPlayer.uuid }
val tradeOffer = CobblemonClient.requests.tradeOffers.find { it.traderId == optionsPacket.targetId }
if (tradeOffer == null) {
CobblemonNetwork.sendToServer(OfferTradePacket(targetPlayer.uuid))
CobblemonNetwork.sendToServer(OfferTradePacket(optionsPacket.targetId))
} else {
CobblemonClient.requests.tradeOffers -= tradeOffer
CobblemonNetwork.sendToServer(AcceptTradeRequestPacket(tradeOffer.tradeOfferId))
@@ -65,18 +67,35 @@ fun createPlayerInteractGui(targetPlayer: PlayerEntity, pokemon: Pokemon): Inter
)
val battle = InteractWheelOption(
iconResource = cobblemonResource("textures/gui/interact/icon_battle.png"),
colour = { if (CobblemonClient.requests.battleChallenges.any { it.challengerId == targetPlayer.uuid }) Vector3f(0F, 0.6F, 0F) else null },
colour = { if (CobblemonClient.requests.battleChallenges.any { it.challengerId == optionsPacket.targetId }) Vector3f(0F, 0.6F, 0F) else null },
onPress = {
val battleRequest = CobblemonClient.requests.battleChallenges.find { it.challengerId == targetPlayer.uuid }
val battleRequest = CobblemonClient.requests.battleChallenges.find { it.challengerId == optionsPacket.targetId }
// This can be improved in future with more detailed battle challenge data.
BattleChallengePacket(targetPlayer.id, pokemon.uuid).sendToServer()
BattleChallengePacket(optionsPacket.numericTargetId, optionsPacket.selectedPokemonId).sendToServer()
closeGUI()
}
)
val options = mutableMapOf(
Orientation.TOP_LEFT to trade,
Orientation.TOP_RIGHT to battle
val spectate = InteractWheelOption(
iconResource = cobblemonResource("textures/gui/interact/icon_spectate_battle.png"),
colour = { if (CobblemonClient.requests.battleChallenges.any { it.challengerId == optionsPacket.targetId }) Vector3f(0F, 0.6F, 0F) else null },
onPress = {
SpectateBattlePacket(optionsPacket.targetId).sendToServer()
closeGUI()
}
)
val options = mutableMapOf<Orientation, InteractWheelOption>()
//The way things are positioned should probably be more thought out if more options are added
optionsPacket.options.map {
if (it.equals(PlayerInteractOptionsPacket.Options.TRADE)) {
options[Orientation.TOP_LEFT] = trade
}
if (it.equals(PlayerInteractOptionsPacket.Options.BATTLE)) {
options[Orientation.TOP_RIGHT] = battle
}
if (it.equals(PlayerInteractOptionsPacket.Options.SPECTATE_BATTLE)) {
options[Orientation.TOP_RIGHT] = spectate
}
}
return InteractWheelGUI(options, Text.translatable("cobblemon.ui.interact.player"))
}
@@ -11,15 +11,14 @@ package com.cobblemon.mod.common.client.keybind.keybinds
import com.cobblemon.mod.common.CobblemonNetwork.sendPacketToServer
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.gui.battle.BattleGUI
import com.cobblemon.mod.common.client.gui.interact.wheel.createPlayerInteractGui
import com.cobblemon.mod.common.client.keybind.CobblemonBlockingKeyBinding
import com.cobblemon.mod.common.client.keybind.KeybindCategories
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.traceFirstEntityCollision
import javax.swing.plaf.basic.BasicSliderUI.ScrollListener
import net.minecraft.client.MinecraftClient
import net.minecraft.client.network.ClientPlayerEntity
import net.minecraft.client.util.InputUtil
@@ -90,7 +89,9 @@ object PartySendBinding : CobblemonBlockingKeyBinding(
private fun processEntityTarget(player: ClientPlayerEntity, pokemon: Pokemon, entity: LivingEntity) {
when (entity) {
is PlayerEntity -> {
MinecraftClient.getInstance().setScreen(createPlayerInteractGui(entity, pokemon))
//This sends a packet to the server with the id of the player
//The server sends a packet back that opens the player interaction menu with the proper options
sendPacketToServer(RequestPlayerInteractionsPacket(entity.uuid, entity.id, pokemon.uuid))
}
is PokemonEntity -> {
if (!entity.canBattle(player)) return
@@ -0,0 +1,21 @@
/*
* 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
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
import com.cobblemon.mod.common.client.gui.interact.wheel.createPlayerInteractGui
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import net.minecraft.client.MinecraftClient
object PlayerInteractOptionsHandler : ClientNetworkPacketHandler<PlayerInteractOptionsPacket> {
override fun handle(packet: PlayerInteractOptionsPacket, client: MinecraftClient) {
MinecraftClient.getInstance().setScreen(createPlayerInteractGui(packet))
}
}
@@ -32,10 +32,10 @@ object BattleInitializeHandler : ClientNetworkPacketHandler<BattleInitializePack
}
val otherSide = if (mySide == packet.side1) packet.side2 else packet.side1
side1.actors.addAll(mySide.actors.map{ actorFromDTO(it, true) })
val sides = listOf(packet.side1, packet.side2)
spectating = !sides.any { it.actors.any { it.uuid == MinecraftClient.getInstance().player?.uuid } }
side1.actors.addAll(mySide.actors.map{ actorFromDTO(it, !spectating) })
side2.actors.addAll(otherSide.actors.map{ actorFromDTO(it, false) })
spectating = sides.any { it.actors.any { it.uuid == MinecraftClient.getInstance().player?.uuid } }
for (side in listOf(side1, side2)) {
side.battle = this
for (actor in side.actors) {
@@ -0,0 +1,90 @@
/*
* 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.boat
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.client.render.OverlayTexture
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.entity.EntityRenderer
import net.minecraft.client.render.entity.EntityRendererFactory
import net.minecraft.client.render.entity.model.BoatEntityModel
import net.minecraft.client.render.entity.model.ChestBoatEntityModel
import net.minecraft.client.render.entity.model.EntityModelLayer
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.util.Identifier
import net.minecraft.util.math.MathHelper
import net.minecraft.util.math.RotationAxis
import org.joml.Quaternionf
class CobblemonBoatRenderer(ctx: EntityRendererFactory.Context, private val hasChest: Boolean) : EntityRenderer<CobblemonBoatEntity>(ctx) {
private val boatModels = hashMapOf<CobblemonBoatType, Pair<Identifier, BoatEntityModel>>()
init {
this.shadowRadius = 0.8F
CobblemonBoatType.values().forEach { type ->
this.boatModels[type] = generateTextureIdentifier(type, this.hasChest) to generateBoatModel(ctx, type, this.hasChest)
}
}
override fun getTexture(entity: CobblemonBoatEntity): Identifier = this.boatModels[entity.boatType]!!.first
override fun render(entity: CobblemonBoatEntity, yaw: Float, tickDelta: Float, matrices: MatrixStack, vertexConsumers: VertexConsumerProvider, light: Int) {
matrices.push()
matrices.translate(0F, 0.375F, 0F)
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180F - yaw))
val h = entity.damageWobbleTicks - tickDelta
val j = (entity.damageWobbleStrength - tickDelta).coerceAtLeast(0F)
if (h > 0F) {
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(MathHelper.sin(h) * h * j / 10F * entity.damageWobbleSide))
}
val k = entity.interpolateBubbleWobble(tickDelta)
if (!MathHelper.approximatelyEquals(k, 0F)) {
matrices.multiply(Quaternionf().setAngleAxis(entity.interpolateBubbleWobble(tickDelta) * 0.017453292F, 1F, 0F, 1F))
}
val (identifier, entityModel) = this.boatModels[entity.boatType]!!
matrices.scale(-1F, -1F, 1F)
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90F))
entityModel.setAngles(entity, tickDelta, 0F, -0.1F, 0F, 0F)
val vertexConsumer = vertexConsumers.getBuffer(entityModel.getLayer(identifier))
entityModel.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 1F, 1F, 1F, 1F)
if (!entity.isSubmergedInWater) {
val vertexConsumer2 = vertexConsumers.getBuffer(RenderLayer.getWaterMask())
entityModel.waterPatch.render(matrices, vertexConsumer2, light, OverlayTexture.DEFAULT_UV)
}
matrices.pop()
super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light)
}
companion object {
private fun generateTextureIdentifier(type: CobblemonBoatType, hasChest: Boolean): Identifier {
val boatSubPath = if (hasChest) "chest_boat" else "boat"
val path = "textures/entity/$boatSubPath/${type.name.lowercase()}.png"
return cobblemonResource(path)
}
private fun generateBoatModel(ctx: EntityRendererFactory.Context, type: CobblemonBoatType, hasChest: Boolean): BoatEntityModel {
val modelLayer = this.createBoatModelLayer(type, hasChest)
val modelPart = ctx.getPart(modelLayer)
return if (hasChest) ChestBoatEntityModel(modelPart) else BoatEntityModel(modelPart)
}
internal fun createBoatModelLayer(type: CobblemonBoatType, hasChest: Boolean): EntityModelLayer {
val boatSubPath = if (hasChest) "chest_boat" else "boat"
val path = "$boatSubPath/${type.name.lowercase()}"
return EntityModelLayer(cobblemonResource(path), "main")
}
}
}
@@ -19,7 +19,7 @@ import net.minecraft.client.model.ModelPart
class PokeBallModel(root: ModelPart) : PoseableEntityModel<EmptyPokeBallEntity>(), PokeBallFrame {
override val rootPart = root.registerChildWithAllChildren("poke_ball")
override val base = getPart("base")
override val base = getPart("bottom")
override val lid = getPart("lid")
override val isForLivingEntityRenderer = false
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.asTransformed
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart
@@ -23,44 +24,50 @@ import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class GolbatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame {
class GolbatModel(root: ModelPart) : PokemonPoseableModel() {
override val rootPart = root.registerChildWithAllChildren("golbat")
override val leftWing = getPart("leftwing")
override val rightWing = getPart("rightwing")
override val portraitScale = 1.55F
override val portraitTranslation = Vec3d(0.0, -0.55, 0.0)
override val portraitTranslation = Vec3d(-0.1, -0.1, 0.0)
override val profileScale = 0.9F
override val profileTranslation = Vec3d(0.0, 0.4, 0.0)
override val profileScale = 0.7F
override val profileTranslation = Vec3d(0.0, 0.7, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var hover: PokemonPose
lateinit var fly: PokemonPose
lateinit var battleidle: PokemonPose
// override val cryAnimation = CryProvider { _, _ -> bedrockStateful("golbat", "cry").setPreventsIdle(false) }
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES - PoseType.HOVER,
transformTicks = 10,
idleAnimations = arrayOf(
//bedrock("golbat", "ground_idle")
)
)
val blink = quirk("blink") { bedrockStateful("golbat", "blink").setPreventsIdle(false) }
sleep = registerPose(
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("golbat", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES - PoseType.HOVER,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { !it.isBattling },
idleAnimations = arrayOf(
bedrock("golbat", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES - PoseType.FLY,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
//bedrock("golbat", "ground_walk")
bedrock("golbat", "ground_walk")
)
)
@@ -68,12 +75,9 @@ class GolbatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame {
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.6F),
timeVariable = { state, _, _ -> state?.animationSeconds ?: 0F },
axis = TransformedModelPart.Y_AXIS
)
bedrock("golbat", "air_idle")
)
)
@@ -81,12 +85,20 @@ class GolbatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame {
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -14F.toRadians(), period = 0.9F, amplitude = 0.9F),
timeVariable = { state, _, _ -> state?.animationSeconds ?: 0F },
axis = TransformedModelPart.Y_AXIS
)
bedrock("golbat", "air_fly")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
idleAnimations = arrayOf(
bedrock("golbat", "battle_idle")
)
)
}
@@ -37,7 +37,6 @@ class KadabraModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Biped
override val profileScale = 0.75F
override val profileTranslation = Vec3d(0.0, 0.6, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var battleidle: PokemonPose
@@ -10,11 +10,14 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.EarJoint
import com.cobblemon.mod.common.client.render.models.blockbench.RangeOfMotion
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.asTransformed
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.EaredFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart.Companion.X_AXIS
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart.Companion.Y_AXIS
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart.Companion.Z_AXIS
@@ -27,81 +30,121 @@ import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.MathConstants.PI
import net.minecraft.util.math.Vec3d
class ZubatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame, EaredFrame {
class ZubatModel(root: ModelPart) : PokemonPoseableModel() {
override val rootPart = root.registerChildWithAllChildren("zubat")
override val leftWing = getPart("leftwing")
override val rightWing = getPart("rightwing")
val wings_folded = getPart("wings_folded")
val wings_open = getPart("wings_open")
private val leftEar = getPart("leftear")
private val rightEar = getPart("rightear")
override val leftEarJoint = EarJoint(leftEar, Z_AXIS, RangeOfMotion(70F.toRadians(), 40F.toRadians()))
override val rightEarJoint = EarJoint(rightEar, Z_AXIS, RangeOfMotion((-70F).toRadians(), (-40F).toRadians()))
override val portraitScale = 1.7F
override val portraitTranslation = Vec3d(0.0, 0.0, 0.0)
override val portraitScale = 2.3F
override val portraitTranslation = Vec3d(0.0, -0.5, 0.0)
override val profileScale = 1.0F
override val profileTranslation = Vec3d(0.0, 0.36, 0.0)
override val profileScale = 0.7F
override val profileTranslation = Vec3d(0.0, 0.7, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var hover: PokemonPose
lateinit var fly: PokemonPose
lateinit var shoulderLeft: PokemonPose
lateinit var shoulderRight: PokemonPose
val shoulderOffset = 0
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("zubat", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val twitch = quirk("twitch") { bedrockStateful("zubat", "eartwitch").setPreventsIdle(false) }
sleep = registerPose(
poseType = PoseType.SLEEP,
transformedParts = arrayOf(
wings_folded.asTransformed().withVisibility(visibility = false),
wings_open.asTransformed().withVisibility(visibility = true),
),
quirks = arrayOf(twitch),
idleAnimations = arrayOf(bedrock("zubat", "sleep"))
)
registerPose(
poseName = "hover",
poseTypes = ALL_POSES - SHOULDER_POSES - PoseType.FLY - PoseType.SLEEP,
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES - PoseType.HOVER,
transformedParts = arrayOf(
wings_folded.asTransformed().withVisibility(visibility = false),
wings_open.asTransformed().withVisibility(visibility = true),
),
transformTicks = 10,
quirks = arrayOf(twitch),
idleAnimations = arrayOf(
bedrock("zubat", "ground_idle")
)
)
registerPose(
poseName = "fly",
poseType = PoseType.FLY,
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
transformedParts = arrayOf(
wings_folded.asTransformed().withVisibility(visibility = false),
wings_open.asTransformed().withVisibility(visibility = true),
),
transformTicks = 10,
quirks = arrayOf(twitch),
idleAnimations = arrayOf(
bedrock("zubat", "ground_walk")
)
)
registerPose(
poseType = PoseType.SHOULDER_LEFT,
idleAnimations = arrayOf(
leftWing.rotation(
function = sineFunction(
amplitude = PI / 3,
period = 1F
),
axis = Z_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
)
),
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
transformedParts = arrayOf(
rootPart.asTransformed().addRotation(X_AXIS, PI / 9).addPosition(Y_AXIS, 4F).addPosition(Z_AXIS, 3F),
leftWing.asTransformed().addRotation(X_AXIS, PI / 3),
rightWing.asTransformed().addRotation(X_AXIS, PI / 3).addRotation(Z_AXIS, -PI / 2)
wings_folded.asTransformed().withVisibility(visibility = false),
wings_open.asTransformed().withVisibility(visibility = true),
),
transformTicks = 10,
quirks = arrayOf(twitch),
idleAnimations = arrayOf(
bedrock("zubat", "air_idle")
)
)
registerPose(
poseType = PoseType.SHOULDER_RIGHT,
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
transformedParts = arrayOf(
wings_folded.asTransformed().withVisibility(visibility = false),
wings_open.asTransformed().withVisibility(visibility = true),
),
quirks = arrayOf(twitch),
transformTicks = 10,
idleAnimations = arrayOf(
rightWing.rotation(
function = sineFunction(
amplitude = PI / 3,
period = 1F
),
axis = Z_AXIS,
timeVariable = { _, _, ageInTicks -> ageInTicks / 20 },
)
bedrock("zubat", "air_fly")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
idleAnimations = arrayOf(
bedrock("zubat", "shoulder_left")
),
transformedParts = arrayOf(
rootPart.asTransformed().addRotation(X_AXIS, PI / 9).addPosition(Y_AXIS, 4F).addPosition(Z_AXIS, 3F),
leftWing.asTransformed().addRotation(X_AXIS, PI / 3).addRotation(Z_AXIS, PI / 2),
rightWing.asTransformed().addRotation(X_AXIS, PI / 3)
rootPart.asTransformed().addPosition(TransformedModelPart.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
idleAnimations = arrayOf(
bedrock("zubat", "shoulder_right")
),
transformedParts = arrayOf(
rootPart.asTransformed().addPosition(TransformedModelPart.X_AXIS, -shoulderOffset)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("zubat", "faint") else null
}
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart
@@ -19,26 +20,37 @@ import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class CrobatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame {
class CrobatModel(root: ModelPart) : PokemonPoseableModel() {
override val rootPart = root.registerChildWithAllChildren("crobat")
override val leftWing = getPart("leftwings")
override val rightWing = getPart("rightwings")
override val portraitScale = 1.8F
override val portraitTranslation = Vec3d(-0.11, -0.77, 0.0)
override val portraitScale = 1.2F
override val portraitTranslation = Vec3d(-0.1, 1.8, 0.0)
override val profileScale = 0.9F
override val profileTranslation = Vec3d(0.0, 0.35, 0.0)
override val profileScale = 0.5F
override val profileTranslation = Vec3d(0.0, 1.2, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var hover: PokemonPose
lateinit var fly: PokemonPose
lateinit var walk: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("crobat", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("crobat", "blink").setPreventsIdle(false) }
sleep = registerPose(
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("crobat", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseType = PoseType.STAND,
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES - PoseType.HOVER,
condition = { !it.isBattling },
transformTicks = 10,
idleAnimations = arrayOf(
bedrock("crobat", "ground_idle")
)
@@ -57,13 +69,9 @@ class CrobatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame {
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("crobat", "ground_idle"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -10F.toRadians(), period = 0.9F, amplitude = 0.6F),
timeVariable = { state, _, _ -> state?.animationSeconds ?: 0F },
axis = TransformedModelPart.Y_AXIS
)
bedrock("crobat", "air_idle")
)
)
@@ -71,13 +79,20 @@ class CrobatModel(root: ModelPart) : PokemonPoseableModel(), BiWingedFrame {
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("crobat", "ground_walk"),
WingFlapIdleAnimation(this,
flapFunction = sineFunction(verticalShift = -14F.toRadians(), period = 0.9F, amplitude = 0.9F),
timeVariable = { state, _, _ -> state?.animationSeconds ?: 0F },
axis = TransformedModelPart.Y_AXIS
)
bedrock("crobat", "air_fly")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
idleAnimations = arrayOf(
bedrock("crobat", "battle_idle")
)
)
}
@@ -8,42 +8,53 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.asTransformed
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.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class HitmontopModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, BipedFrame, BimanualFrame {
class HitmontopModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("hitmontop")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val portraitScale = 2.6F
override val portraitTranslation = Vec3d(-0.26, -0.5, 0.0)
override val profileScale = 0.91F
override val profileTranslation = Vec3d(0.0, 0.4, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var battleidle: PokemonPose
// override val cryAnimation = CryProvider { _, _ -> bedrockStateful("hitmontop", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("hitmontop", "blink").setPreventsIdle(false)}
val blink = quirk("blink") { bedrockStateful("hitmontop", "blink").setPreventsIdle(false) }
sleep = registerPose(
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("hitmontop", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
@@ -53,19 +64,29 @@ class HitmontopModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bip
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("hitmontop", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
bedrock("hitmontop", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("hitmontop", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("hitmontop", "faint") else null
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = bedrockStateful("hitmontop", "faint")
}
@@ -8,42 +8,59 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.asTransformed
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.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class TyrogueModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, BipedFrame, BimanualFrame {
class TyrogueModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("tyrogue")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val portraitScale = 2.56F
override val portraitTranslation = Vec3d(-0.24, 0.1, 0.0)
override val profileScale = 0.73F
override val profileTranslation = Vec3d(-0.03, 0.7, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var shoulderLeft: PokemonPose
lateinit var shoulderRight: PokemonPose
lateinit var battleidle: PokemonPose
val shoulderOffset = 3
// override val cryAnimation = CryProvider { _, _ -> bedrockStateful("tyrogue", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("tyrogue", "blink").setPreventsIdle(false)}
val blink = quirk("blink") { bedrockStateful("tyrogue", "blink").setPreventsIdle(false) }
sleep = registerPose(
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("tyrogue", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
@@ -53,19 +70,55 @@ class TyrogueModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Biped
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("tyrogue", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
bedrock("tyrogue", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("tyrogue", "battle_idle")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
condition = { !it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("tyrogue", "shoulder_left")
),
transformedParts = arrayOf(
rootPart.asTransformed().addPosition(TransformedModelPart.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
condition = { !it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("tyrogue", "shoulder_right")
),
transformedParts = arrayOf(
rootPart.asTransformed().addPosition(TransformedModelPart.X_AXIS, -shoulderOffset)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("tyrogue", "faint") else null
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = if (state.isPosedIn(standing, walk, battleidle, sleep)) bedrockStateful("tyrogue", "faint") else null
}
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedW
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.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -35,6 +36,8 @@ class BeldumModel (root: ModelPart) : PokemonPoseableModel() {
lateinit var sleep: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("beldum", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("beldum", "blink").setPreventsIdle(false)}
val quirk = quirk("quirk") { bedrockStateful("beldum", "quirk_spin").setPreventsIdle(false)}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -30,6 +31,8 @@ class MetagrossModel (root: ModelPart) : PokemonPoseableModel() {
lateinit var sleep: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("metagross", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("metagross", "blink").setPreventsIdle(false)}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -30,6 +31,8 @@ class MetangModel (root: ModelPart) : PokemonPoseableModel() {
lateinit var sleep: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("metang", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("metang", "blink").setPreventsIdle(false)}
@@ -8,64 +8,87 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class MightyenaModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, QuadrupedFrame {
class MightyenaModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("mightyena")
override val head = getPart("head")
override val hindLeftLeg = getPart("leg_left")
override val hindRightLeg = getPart("leg_right")
override val foreLeftLeg = getPart("arm_left")
override val foreRightLeg = getPart("arm_right")
override val portraitScale = 2.2F
override val portraitTranslation = Vec3d(-0.8, 0.6, 0.0)
override val profileScale = 0.6F
override val profileTranslation = Vec3d(0.0, 0.8, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("mightyena", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("mightyena", "blink").setPreventsIdle(false) }
val laugh_out_battle = quirk("laugh_out_battle", secondsBetweenOccurrences = 120F to 240F) { bedrockStateful("mightyena", "quirk").setPreventsIdle(false) }
val laugh_in_battle = quirk("laugh_in_battle", secondsBetweenOccurrences = 30F to 60F) { bedrockStateful("mightyena", "quirk").setPreventsIdle(false) }
val sleep_quirk = quirk("sleep_quirk", secondsBetweenOccurrences = 30F to 60F) { bedrockStateful("mightyena", "sleep_quirk").setPreventsIdle(false) }
sleep = registerPose(
poseType = PoseType.SLEEP,
quirks = arrayOf(sleep_quirk),
idleAnimations = arrayOf(bedrock("mightyena", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = UI_POSES + STATIONARY_POSES,
quirks = arrayOf(blink),
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink,laugh_out_battle),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("mightyena","ground_idle")
bedrock("mightyena", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
QuadrupedWalkAnimation(this, periodMultiplier = 0.8F, amplitudeMultiplier = 0.8F),
bedrock("mightyena","ground_idle")
bedrock("mightyena", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink,laugh_in_battle),
condition = { it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("mightyena", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("mightyena", "faint") else null
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = bedrockStateful("mightyena", "faint")
}
@@ -49,7 +49,7 @@ class ShroomishModel(root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bip
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
quirks = arrayOf(blink),
condition = { it.isBattling },
condition = { !it.isBattling },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("shroomish", "ground_idle")
@@ -68,7 +68,6 @@ class VolbeatModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bipe
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isTouchingWater },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("volbeat", "air_idle")
@@ -80,7 +79,6 @@ class VolbeatModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Bipe
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isTouchingWater },
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("volbeat", "air_fly")
@@ -8,12 +8,16 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen4
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityState
import com.cobblemon.mod.common.client.render.models.blockbench.asTransformed
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.TransformedModelPart
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
@@ -34,6 +38,10 @@ class TurtwigModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quad
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var shoulderLeft: PokemonPose
lateinit var shoulderRight: PokemonPose
val shoulderOffset = 3
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("turtwig", "cry").setPreventsIdle(false) }
@@ -65,5 +73,33 @@ class TurtwigModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame, Quad
bedrock("turtwig", "ground_walk")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("turtwig", "shoulder_left")
),
transformedParts = arrayOf(
rootPart.asTransformed().addPosition(TransformedModelPart.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
singleBoneLook(),
bedrock("turtwig", "shoulder_right")
),
transformedParts = arrayOf(
rootPart.asTransformed().addPosition(TransformedModelPart.X_AXIS, -shoulderOffset)
)
)
}
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = bedrockStateful("turtwig", "faint")
}
@@ -0,0 +1,57 @@
/*
* 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.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class ChandelureModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("chandelure")
override val head = getPart("head")
override val portraitScale = 2.0F
override val portraitTranslation = Vec3d(-0.3, -1.2, 0.0)
override val profileScale = 0.8F
override val profileTranslation = Vec3d(0.0, 0.5, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override fun registerPoses() {
// val blink = quirk("blink") { bedrockStateful("chandelure", "blink").setPreventsIdle(false) }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
// quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("chandelure", "idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
// quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("chandelure", "idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("chandelure", "faint") else null
}
@@ -0,0 +1,57 @@
/*
* 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.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class LampentModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("lampent")
override val head = getPart("head")
override val portraitScale = 2.0F
override val portraitTranslation = Vec3d(-0.3, -1.2, 0.0)
override val profileScale = 0.8F
override val profileTranslation = Vec3d(0.0, 0.5, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("lampent", "blink").setPreventsIdle(false) }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("lampent", "idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("lampent", "idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("lampent", "faint") else null
}
@@ -0,0 +1,57 @@
/*
* 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.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.ModelPart
import net.minecraft.util.math.Vec3d
class LitwickModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("litwick")
override val head = getPart("head")
override val portraitScale = 2.0F
override val portraitTranslation = Vec3d(-0.3, -1.2, 0.0)
override val profileScale = 0.8F
override val profileTranslation = Vec3d(0.0, 0.5, 0.0)
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("litwick", "blink").setPreventsIdle(false) }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("litwick", "idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
bedrock("litwick", "idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PoseableEntityState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("litwick", "faint") else null
}
@@ -41,9 +41,10 @@ class TrevenantModel (root: ModelPart) : PokemonPoseableModel() {
poseType = PoseType.SLEEP,
idleAnimations = arrayOf(bedrock("trevenant", "sleep"))
)
standing = registerPose(
poseName = "stand",
poseTypes = PoseType.STATIONARY_POSES - PoseType.HOVER - PoseType.FLOAT + PoseType.UI_POSES,
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
condition = { !it.isBattling },
transformTicks = 10,
quirks = arrayOf(blink),
@@ -53,7 +54,7 @@ class TrevenantModel (root: ModelPart) : PokemonPoseableModel() {
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY - PoseType.SWIM,
poseTypes = PoseType.MOVING_POSES,
transformTicks = 5,
quirks = arrayOf(blink),
idleAnimations = arrayOf(
@@ -25,7 +25,6 @@ class KomalaModel (root: ModelPart) : PokemonPoseableModel() {
override val profileScale = 0.8F
override val profileTranslation = Vec3d(0.0, 0.5, 0.0)
lateinit var sleep: PokemonPose
lateinit var standing: PokemonPose
// override val cryAnimation = CryProvider { _, _ -> bedrockStateful("komala", "cry").setPreventsIdle(false) }
@@ -62,5 +62,5 @@ class EiscueModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = if (state.isPosedIn(standing, walk, sleep)) bedrockStateful("eiscue_ice", "faint") else null
) = bedrockStateful("eiscue_ice", "faint")
}
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedW
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.PokemonPose
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPoseableModel
import com.cobblemon.mod.common.entity.PoseType
@@ -37,6 +38,8 @@ class QuaxwellModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
lateinit var sleep: PokemonPose
lateinit var battleidle: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("quaxwell", "cry").setPreventsIdle(false) }
override fun registerPoses() {
val blink = quirk("blink") { bedrockStateful("quaxwell", "blink").setPreventsIdle(false) }
sleep = registerPose(
@@ -47,7 +47,6 @@ class SquawkabillyModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame,
lateinit var flying: PokemonPose
lateinit var shoulderLeft: PokemonPose
lateinit var shoulderRight: PokemonPose
lateinit var sleep: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("squawkabilly", "cry").setPreventsIdle(false) }
@@ -31,7 +31,7 @@ class TandemausModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
lateinit var standing: PokemonPose
lateinit var walk: PokemonPose
lateinit var sleep: PokemonPose
// lateinit var sleep: PokemonPose
override val cryAnimation = CryProvider { _, _ -> bedrockStateful("tandemaus", "cry").setPreventsIdle(false) }
@@ -69,19 +69,18 @@ class TandemausModel (root: ModelPart) : PokemonPoseableModel(), HeadedFrame {
)
)
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
transformTicks = 10,
quirks = arrayOf(blink1, blink2),
idleAnimations = arrayOf(
bedrock("tandemaus", "ground_idle")
//bedrock("tandemaus", "sleep")
)
)
// sleep = registerPose(
// poseName = "sleep",
// poseType = PoseType.SLEEP,
// transformTicks = 10,
// quirks = arrayOf(blink1, blink2),
// idleAnimations = arrayOf(
// bedrock("tandemaus", "sleep")
// )
// )
}
override fun getFaintAnimation(
pokemonEntity: PokemonEntity,
state: PoseableEntityState<PokemonEntity>
) = if (state.isNotPosedIn(sleep)) bedrockStateful("tandemaus", "faint") else null
) = bedrockStateful("tandemaus", "faint")
}
@@ -586,6 +586,9 @@ object PokemonModelRepository : VaryingModelRepository<PokemonEntity, PokemonPos
inbuilt("clodsire", ::ClodsireModel)
inbuilt("teddiursa", ::TeddiursaModel)
inbuilt("ursaring", ::UrsaringModel)
inbuilt("litwick", ::LitwickModel)
inbuilt("lampent", ::LampentModel)
inbuilt("chandelure", ::ChandelureModel)
}
override fun loadJsonPoser(json: String): (Bone) -> PokemonPoseableModel {
@@ -131,6 +131,9 @@ class CobblemonConfig {
@NodeCategory(category = Category.Battles)
var luckyEggMultiplier = 1.5
@NodeCategory(category = Category.Battles)
var allowSpectating = true
@NodeCategory(category = Category.Pokemon)
var experienceMultiplier = 2F
@@ -205,10 +208,6 @@ class CobblemonConfig {
@NodeCategory(Category.Spawning)
var teraTypeRate = 20F
@NodeCategory(Category.Pokemon)
@LastChangedVersion("1.4.0")
var consumeHeldItems = true
@NodeCategory(Category.World)
var defaultPasturedPokemonLimit = 16
@@ -0,0 +1,137 @@
/*
* 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.entity.boat
import com.cobblemon.mod.common.CobblemonEntities
import com.cobblemon.mod.common.mixin.accessor.BoatEntityAccessor
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.WoodType
import net.minecraft.entity.EntityType
import net.minecraft.entity.data.DataTracker
import net.minecraft.entity.data.TrackedDataHandlerRegistry
import net.minecraft.entity.vehicle.BoatEntity
import net.minecraft.item.Item
import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtString
import net.minecraft.network.listener.ClientPlayPacketListener
import net.minecraft.network.packet.Packet
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket
import net.minecraft.registry.tag.FluidTags
import net.minecraft.text.Text
import net.minecraft.util.math.BlockPos
import net.minecraft.world.GameRules
import net.minecraft.world.World
@Suppress("unused")
open class CobblemonBoatEntity(entityType: EntityType<out BoatEntity>, world: World) : BoatEntity(entityType, world) {
constructor(world: World) : this(CobblemonEntities.BOAT, world)
// This exists cause super passes in vanilla boat entity type
constructor(world: World, x: Double, y: Double, z: Double) : this(CobblemonEntities.BOAT, world) {
this.setPosition(x, y, z)
this.prevX = x
this.prevY = y
this.prevZ = z
}
/**
* The [CobblemonBoatType] of this boat.
*/
var boatType: CobblemonBoatType
get() = CobblemonBoatType.ofOrdinal(this.dataTracker.get(TYPE_TRACKED_DATA))
set(value) {
this.dataTracker.set(TYPE_TRACKED_DATA, value.ordinal)
}
/**
* The [WoodType] that represents this boat.
*/
val woodType: WoodType get() = this.boatType.woodType
/**
* The [Block] that represents the base material for this boat.
*/
val baseBlock: Block get() = this.boatType.baseBlock
override fun asItem(): Item = this.boatType.boatItem
override fun createSpawnPacket(): Packet<ClientPlayPacketListener> = EntitySpawnS2CPacket(this)
override fun initDataTracker() {
super.initDataTracker()
this.dataTracker.startTracking(TYPE_TRACKED_DATA, CobblemonBoatType.APRICORN.ordinal)
}
override fun getDefaultName(): Text = EntityType.BOAT.name
override fun readCustomDataFromNbt(nbt: NbtCompound) {
if (nbt.contains(TYPE_KEY, NbtElement.STRING_TYPE.toInt())) {
this.boatType = CobblemonBoatType.valueOf(nbt.getString(TYPE_KEY))
}
}
override fun writeCustomDataToNbt(nbt: NbtCompound) {
nbt.put(TYPE_KEY, NbtString.of(this.boatType.name))
}
override fun setVariant(type: Type) {
throw UnsupportedOperationException("The vanilla boat type is not present in the Cobblemon implementation use the type property")
}
override fun getVariant(): Type {
throw UnsupportedOperationException("The vanilla boat type is not present in the Cobblemon implementation use the type property")
}
override fun getMountedHeightOffset(): Double = this.boatType.mountedOffset
override fun fall(heightDifference: Double, onGround: Boolean, state: BlockState, landedPosition: BlockPos) {
val accessor = this.accessor()
accessor.setFallVelocity(this.velocity.y)
if (!this.hasVehicle()) {
return
}
if (!this.world.getFluidState(this.blockPos.down()).isIn(FluidTags.WATER) && heightDifference < 0.0) {
this.fallDistance -= heightDifference.toFloat()
}
if (!onGround) {
return
}
if (this.fallDistance < 3F || accessor.location != Location.ON_LAND) {
this.onLanding()
return
}
this.handleFallDamage(this.fallDistance, 1F, this.damageSources.fall())
if (this.world.isClient || this.isRemoved) {
return
}
this.kill()
if (this.world.gameRules.getBoolean(GameRules.DO_ENTITY_DROPS)) {
repeat(3) {
this.dropItem(this.boatType.baseBlock)
}
repeat(2) {
this.dropItem(Items.STICK)
}
}
}
protected fun accessor(): BoatEntityAccessor = this as BoatEntityAccessor
companion object {
private const val TYPE_KEY = "type"
private val TYPE_TRACKED_DATA = DataTracker.registerData(CobblemonBoatEntity::class.java, TrackedDataHandlerRegistry.INTEGER)
}
}
@@ -0,0 +1,62 @@
/*
* 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.entity.boat
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import net.minecraft.block.Block
import net.minecraft.block.WoodType
import net.minecraft.item.Item
import net.minecraft.util.StringIdentifiable
/**
* Represents the various wooden boats in Cobblemon.
*
*/
enum class CobblemonBoatType(val mountedOffset: Double) : StringIdentifiable {
APRICORN(-0.1);
/**
* The base [Item] form of this [CobblemonBoatType].
*/
val boatItem: Item get() = when (this) {
APRICORN -> CobblemonItems.APRICORN_BOAT
}
/**
* The base [Item] form of this [CobblemonBoatType] with a chest.
*/
val chestBoatItem: Item get() = when (this) {
APRICORN -> CobblemonItems.APRICORN_CHEST_BOAT
}
/**
* The base [Block] form of this [CobblemonBoatType].
*/
val baseBlock: Block get() = when (this) {
APRICORN -> CobblemonBlocks.APRICORN_PLANKS
}
/**
* The [WoodType] form of this [CobblemonBoatType].
*/
val woodType: WoodType get() = when (this) {
APRICORN -> CobblemonBlocks.APRICORN_WOOD_TYPE
}
override fun asString(): String = this.name.lowercase()
companion object {
internal fun ofOrdinal(ordinal: Int) = CobblemonBoatType.values()[ordinal]
}
}
@@ -0,0 +1,104 @@
/*
* 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.entity.boat
import com.cobblemon.mod.common.CobblemonEntities
import net.minecraft.entity.EntityType
import net.minecraft.entity.RideableInventory
import net.minecraft.entity.mob.PiglinBrain
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.entity.vehicle.VehicleInventory
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.screen.GenericContainerScreenHandler
import net.minecraft.screen.ScreenHandler
import net.minecraft.util.Identifier
import net.minecraft.util.collection.DefaultedList
import net.minecraft.world.World
import net.minecraft.world.event.GameEvent
@Suppress("unused")
class CobblemonChestBoatEntity(entityType: EntityType<CobblemonChestBoatEntity>, world: World) : CobblemonBoatEntity(entityType, world), RideableInventory, VehicleInventory {
constructor(world: World) : this(CobblemonEntities.CHEST_BOAT, world)
// This exists cause super passes in vanilla boat entity type
constructor(world: World, x: Double, y: Double, z: Double) : this(CobblemonEntities.CHEST_BOAT, world) {
this.setPosition(x, y, z)
this.prevX = x
this.prevY = y
this.prevZ = z
}
private var inventory = this.emptyInventory()
private var lootTableId: Identifier? = null
private var lootTableSeed = 0L
override fun openInventory(player: PlayerEntity) {
player.openHandledScreen(this)
if (!player.world.isClient) {
this.emitGameEvent(GameEvent.CONTAINER_OPEN, player)
PiglinBrain.onGuardedBlockInteracted(player, true)
}
}
override fun clear() = this.clearInventory()
override fun size(): Int = INVENTORY_SLOTS
override fun getStack(slot: Int): ItemStack = this.getInventoryStack(slot)
override fun removeStack(slot: Int, amount: Int): ItemStack = this.removeInventoryStack(slot, amount)
override fun removeStack(slot: Int): ItemStack = this.removeInventoryStack(slot)
override fun setStack(slot: Int, stack: ItemStack) = this.setInventoryStack(slot, stack)
override fun markDirty() {}
override fun canPlayerUse(player: PlayerEntity): Boolean = this.canPlayerAccess(player)
override fun createMenu(syncId: Int, playerInventory: PlayerInventory, player: PlayerEntity): ScreenHandler? {
if (this.lootTableId != null && player.isSpectator) {
return null
}
this.generateInventoryLoot(playerInventory.player)
return GenericContainerScreenHandler.createGeneric9x3(syncId, playerInventory, this)
}
override fun getLootTableId(): Identifier? = this.lootTableId
override fun setLootTableId(lootTableId: Identifier?) {
this.lootTableId = lootTableId
}
override fun getLootTableSeed(): Long = this.lootTableSeed
override fun setLootTableSeed(lootTableSeed: Long) {
this.lootTableSeed = lootTableSeed
}
override fun getInventory(): DefaultedList<ItemStack> = this.inventory
override fun resetInventory() {
this.inventory = this.emptyInventory()
}
override fun asItem(): Item = this.boatType.chestBoatItem
private fun emptyInventory(): DefaultedList<ItemStack> = DefaultedList.ofSize(INVENTORY_SLOTS, ItemStack.EMPTY)
companion object {
private const val INVENTORY_SLOTS = 27
}
}
@@ -342,8 +342,12 @@ class PokemonEntity(
owner.getWorld().playSoundServer(pos, CobblemonSounds.POKE_BALL_RECALL, volume = 0.6F)
phasingTargetId.set(owner.id)
beamModeEmitter.set(2)
val state = pokemon.state;
afterOnMain(seconds = SEND_OUT_DURATION) {
pokemon.recall()
// only recall if the pokemon hasn't been recalled yet for this state
if (state == pokemon.state) {
pokemon.recall()
}
future.complete(pokemon)
}
} else {
@@ -552,6 +556,13 @@ class PokemonEntity(
player.setStackInHand(hand, milkBucket)
return ActionResult.success(world.isClient)
}
} else if (itemStack.isOf(Items.BOWL)) {
if (pokemon.getFeature<FlagSpeciesFeature>(DataKeys.IS_MOOSHTANK) != null) {
player.playSound(SoundEvents.ENTITY_MOOSHROOM_MILK, 1.0f, 1.0f)
val mushroomStew = ItemUsage.exchangeStack(itemStack, player, Items.MUSHROOM_STEW.defaultStack)
player.setStackInHand(hand, mushroomStew)
return ActionResult.success(world.isClient)
}
}
if (hand == Hand.MAIN_HAND && player is ServerPlayerEntity && pokemon.getOwnerPlayer() == player) {
@@ -0,0 +1,75 @@
/*
* 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.item
import com.cobblemon.mod.common.entity.boat.CobblemonBoatEntity
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.entity.boat.CobblemonChestBoatEntity
import net.minecraft.entity.Entity
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.predicate.entity.EntityPredicates
import net.minecraft.stat.Stats
import net.minecraft.util.Hand
import net.minecraft.util.TypedActionResult
import net.minecraft.util.hit.HitResult
import net.minecraft.world.RaycastContext.FluidHandling
import net.minecraft.world.World
import net.minecraft.world.event.GameEvent
class CobblemonBoatItem(val boatType: CobblemonBoatType, val hasChest: Boolean, settings: Settings) : CobblemonItem(settings) {
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
val stack = user.getStackInHand(hand)
val hitResult = raycast(world, user, FluidHandling.ANY)
if (hitResult.type == HitResult.Type.MISS) {
return TypedActionResult.pass(stack)
}
val vec3d = user.getRotationVec(1F)
val eyePos = user.eyePos
world.getOtherEntities(user, user.boundingBox.stretch(vec3d.multiply(5.0)).expand(1.0), RIDERS).forEach { entity ->
val box = entity.boundingBox.expand(entity.targetingMargin.toDouble())
if (box.contains(eyePos)) {
return TypedActionResult.pass(stack)
}
}
if (hitResult.type != HitResult.Type.BLOCK) {
return TypedActionResult.pass(stack)
}
val boatEntity = this.createBoat(world, hitResult)
boatEntity.boatType = this.boatType
boatEntity.yaw = user.yaw
if (!world.isSpaceEmpty(boatEntity, boatEntity.boundingBox)) {
return TypedActionResult.fail(stack)
}
if (!world.isClient) {
world.spawnEntity(boatEntity)
world.emitGameEvent(user, GameEvent.ENTITY_PLACE, hitResult.pos)
if (!user.abilities.creativeMode) {
stack.decrement(1)
}
}
user.incrementStat(Stats.USED.getOrCreateStat(this))
return TypedActionResult.success(stack, world.isClient)
}
private fun createBoat(world: World, hitResult: HitResult): CobblemonBoatEntity {
if (this.hasChest) {
return CobblemonChestBoatEntity(world, hitResult.pos.x, hitResult.pos.y, hitResult.pos.z)
}
return CobblemonBoatEntity(world, hitResult.pos.x, hitResult.pos.y, hitResult.pos.z)
}
companion object {
private val RIDERS = EntityPredicates.EXCEPT_SPECTATOR.and(Entity::canHit)
}
}
@@ -10,10 +10,11 @@ package com.cobblemon.mod.common.item.group
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.item.Item
import net.minecraft.item.ItemConvertible
import net.minecraft.item.ItemGroup
import net.minecraft.item.ItemGroup.*
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKey
import net.minecraft.text.Text
@@ -25,7 +26,7 @@ object CobblemonItemGroups {
// See https://docs.google.com/spreadsheets/d/1QgaIlW-S9A-Blqhc-5G7OO3igaQdEAiYQqVEPnEBFmc/edit#gid=978365418 for what goes what
private val ALL = arrayListOf<ItemGroupHolder>()
private val INJECTORS = arrayListOf<ItemGroupInjector>()
private val INJECTORS = hashMapOf<RegistryKey<ItemGroup>, (injector: Injector) -> Unit>()
@JvmStatic val BLOCKS_KEY = this.create("blocks", this::blockEntries) { ItemStack(CobblemonItems.PC) }
@JvmStatic val POKEBALLS_KEY = this.create("pokeball", this::pokeballentries) { ItemStack(CobblemonItems.POKE_BALL) }
@@ -42,15 +43,18 @@ object CobblemonItemGroups {
@JvmStatic val EVOLUTION_ITEMS get() = Registries.ITEM_GROUP.get(EVOLUTION_ITEMS_KEY)
@JvmStatic val FOOD_INJECTIONS = this.inject(RegistryKey.of(Registries.ITEM_GROUP.key, Identifier("food_and_drinks")), this::foodInjections)
@JvmStatic val TOOLS_AND_UTILITIES_INJECTIONS = this.inject(RegistryKey.of(Registries.ITEM_GROUP.key, Identifier("tools_and_utilities")), this::toolsAndUtilitiesInjections)
fun register(consumer: (holder: ItemGroupHolder) -> ItemGroup) {
ALL.forEach(consumer::invoke)
}
fun inject(consumer: (injector: ItemGroupInjector) -> Unit) {
INJECTORS.forEach(consumer)
fun inject(tabKey: RegistryKey<ItemGroup>, injector: Injector) {
INJECTORS[tabKey]?.invoke(injector)
}
fun injectorKeys(): Collection<RegistryKey<ItemGroup>> = this.INJECTORS.keys
data class ItemGroupHolder(
val key: RegistryKey<ItemGroup>,
val displayIconProvider: () -> ItemStack,
@@ -58,23 +62,17 @@ object CobblemonItemGroups {
val displayName: Text = Text.translatable("itemGroup.${key.value.namespace}.${key.value.path}")
)
data class ItemGroupInjector(
val key: RegistryKey<ItemGroup>,
val entryInjector: (displayContext: DisplayContext) -> List<Item>,
)
private fun create(name: String, entryCollector: EntryCollector, displayIconProvider: () -> ItemStack): RegistryKey<ItemGroup> {
val key = RegistryKey.of(Registries.ITEM_GROUP.key, cobblemonResource(name))
this.ALL += ItemGroupHolder(key, displayIconProvider, entryCollector)
return key
}
private fun inject(key: RegistryKey<ItemGroup>, entryInjector: (displayContext: DisplayContext) -> List<Item>): ItemGroupInjector {
val injector = ItemGroupInjector(key, entryInjector)
this.INJECTORS += injector
return injector
private fun inject(key: RegistryKey<ItemGroup>, consumer: (injector: Injector) -> Unit): (injector: Injector) -> Unit {
this.INJECTORS[key] = consumer
return consumer
}
private fun agricultureEntries(displayContext: DisplayContext, entries: Entries) {
entries.add(CobblemonItems.MEDICINAL_LEEK)
entries.add(CobblemonItems.BIG_ROOT)
@@ -146,6 +144,8 @@ object CobblemonItemGroups {
entries.add(CobblemonItems.APRICORN_TRAPDOOR)
entries.add(CobblemonItems.APRICORN_BUTTON)
entries.add(CobblemonItems.APRICORN_PRESSURE_PLATE)
entries.add(CobblemonItems.APRICORN_SIGN)
entries.add(CobblemonItems.APRICORN_HANGING_SIGN)
entries.add(CobblemonItems.APRICORN_LEAVES)
entries.add(CobblemonItems.DAWN_STONE_ORE)
entries.add(CobblemonItems.DEEPSLATE_DAWN_STONE_ORE)
@@ -169,7 +169,7 @@ object CobblemonItemGroups {
entries.add(CobblemonItems.WATER_STONE_ORE)
entries.add(CobblemonItems.DEEPSLATE_WATER_STONE_ORE)
}
private fun consumableEntries(displayContext: DisplayContext, entries: Entries) {
entries.add(CobblemonItems.ROASTED_LEEK)
entries.add(CobblemonItems.LEEK_AND_POTATO_STEW)
@@ -301,70 +301,166 @@ object CobblemonItemGroups {
}
private fun heldItemEntries(displayContext: DisplayContext, entries: Entries) {
entries.add(CobblemonItems.ABILITY_SHIELD)
entries.add(CobblemonItems.ABSORB_BULB)
entries.add(CobblemonItems.AIR_BALLOON)
entries.add(CobblemonItems.AMULET_COIN)
entries.add(CobblemonItems.ASSAULT_VEST)
entries.add(CobblemonItems.BIG_ROOT)
entries.add(CobblemonItems.BINDING_BAND)
entries.add(CobblemonItems.BLACK_BELT)
entries.add(CobblemonItems.BLACK_GLASSES)
entries.add(CobblemonItems.BLACK_SLUDGE)
entries.add(CobblemonItems.BLUNDER_POLICY)
entries.add(CobblemonItems.BRIGHT_POWDER)
entries.add(CobblemonItems.CELL_BATTERY)
entries.add(CobblemonItems.CHARCOAL)
entries.add(CobblemonItems.CHOICE_BAND)
entries.add(CobblemonItems.CHOICE_SCARF)
entries.add(CobblemonItems.CHOICE_SPECS)
entries.add(CobblemonItems.CLEANSE_TAG)
entries.add(CobblemonItems.CLEAR_AMULET)
entries.add(CobblemonItems.COVERT_CLOAK)
entries.add(CobblemonItems.DAMP_ROCK)
entries.add(CobblemonItems.DEEP_SEA_SCALE)
entries.add(CobblemonItems.DEEP_SEA_TOOTH)
entries.add(CobblemonItems.DESTINY_KNOT)
entries.add(CobblemonItems.DRAGON_FANG)
entries.add(CobblemonItems.EJECT_BUTTON)
entries.add(CobblemonItems.EJECT_PACK)
entries.add(CobblemonItems.ELECTRIC_SEED)
entries.add(CobblemonItems.EVERSTONE)
entries.add(CobblemonItems.EXPERT_BELT)
entries.add(CobblemonItems.EXP_SHARE)
entries.add(CobblemonItems.FAIRY_FEATHER)
entries.add(CobblemonItems.FLAME_ORB)
entries.add(CobblemonItems.FLOAT_STONE)
entries.add(CobblemonItems.FOCUS_BAND)
entries.add(CobblemonItems.FOCUS_SASH)
entries.add(CobblemonItems.GRASSY_SEED)
entries.add(CobblemonItems.GRIP_CLAW)
entries.add(CobblemonItems.HARD_STONE)
entries.add(CobblemonItems.HEAT_ROCK)
entries.add(CobblemonItems.HEAVY_DUTY_BOOTS)
entries.add(CobblemonItems.ICY_ROCK)
entries.add(CobblemonItems.IRON_BALL)
entries.add(CobblemonItems.KINGS_ROCK)
entries.add(CobblemonItems.LAGGING_TAIL)
entries.add(CobblemonItems.LEFTOVERS)
entries.add(CobblemonItems.LIFE_ORB)
entries.add(CobblemonItems.LIGHT_BALL)
entries.add(CobblemonItems.LIGHT_CLAY)
entries.add(CobblemonItems.LOADED_DICE)
entries.add(CobblemonItems.LUCKY_EGG)
entries.add(CobblemonItems.LUMINOUS_MOSS)
entries.add(CobblemonItems.MAGNET)
entries.add(CobblemonItems.MENTAL_HERB)
entries.add(CobblemonItems.METAL_POWDER)
entries.add(CobblemonItems.METRONOME)
entries.add(CobblemonItems.MIRACLE_SEED)
entries.add(CobblemonItems.MIRROR_HERB)
entries.add(CobblemonItems.MISTY_SEED)
entries.add(CobblemonItems.MUSCLE_BAND)
entries.add(CobblemonItems.MYSTIC_WATER)
entries.add(CobblemonItems.NEVER_MELT_ICE)
entries.add(CobblemonItems.POISON_BARB)
entries.add(CobblemonItems.POWER_HERB)
entries.add(CobblemonItems.QUICK_CLAW)
entries.add(CobblemonItems.QUICK_POWDER)
entries.add(CobblemonItems.RAZOR_CLAW)
entries.add(CobblemonItems.RAZOR_FANG)
entries.add(CobblemonItems.ROCKY_HELMET)
entries.add(CobblemonItems.SAFETY_GOGGLES)
entries.add(CobblemonItems.SHARP_BEAK)
entries.add(CobblemonItems.SILK_SCARF)
entries.add(CobblemonItems.SILVER_POWDER)
entries.add(CobblemonItems.SOFT_SAND)
entries.add(CobblemonItems.SPELL_TAG)
entries.add(CobblemonItems.TWISTED_SPOON)
entries.add(CobblemonItems.WHITE_HERB)
entries.add(CobblemonItems.WISE_GLASSES)
entries.add(CobblemonItems.POWER_ANKLET)
entries.add(CobblemonItems.POWER_BAND)
entries.add(CobblemonItems.POWER_BELT)
entries.add(CobblemonItems.POWER_BRACER)
entries.add(CobblemonItems.POWER_HERB)
entries.add(CobblemonItems.POWER_LENS)
entries.add(CobblemonItems.POWER_WEIGHT)
entries.add(CobblemonItems.PROTECTIVE_PADS)
entries.add(CobblemonItems.PSYCHIC_SEED)
entries.add(CobblemonItems.PUNCHING_GLOVE)
entries.add(CobblemonItems.QUICK_CLAW)
entries.add(CobblemonItems.QUICK_POWDER)
entries.add(CobblemonItems.RAZOR_CLAW)
entries.add(CobblemonItems.RAZOR_FANG)
entries.add(CobblemonItems.RED_CARD)
entries.add(CobblemonItems.RING_TARGET)
entries.add(CobblemonItems.ROCKY_HELMET)
entries.add(CobblemonItems.ROOM_SERVICE)
entries.add(CobblemonItems.SAFETY_GOGGLES)
entries.add(CobblemonItems.SCOPE_LENS)
entries.add(CobblemonItems.SHARP_BEAK)
entries.add(CobblemonItems.SHED_SHELL)
entries.add(CobblemonItems.SHELL_BELL)
entries.add(CobblemonItems.SILK_SCARF)
entries.add(CobblemonItems.SILVER_POWDER)
entries.add(CobblemonItems.SMOKE_BALL)
entries.add(CobblemonItems.SMOOTH_ROCK)
entries.add(CobblemonItems.SOFT_SAND)
entries.add(CobblemonItems.SOOTHE_BELL)
entries.add(CobblemonItems.SPELL_TAG)
entries.add(CobblemonItems.STICKY_BARB)
entries.add(CobblemonItems.TERRAIN_EXTRUDER)
entries.add(CobblemonItems.THROAT_SPRAY)
entries.add(CobblemonItems.TOXIC_ORB)
entries.add(CobblemonItems.TWISTED_SPOON)
entries.add(CobblemonItems.UTILITY_UMBRELLA)
entries.add(CobblemonItems.WEAKNESS_POLICY)
entries.add(CobblemonItems.WHITE_HERB)
entries.add(CobblemonItems.WIDE_LENS)
entries.add(CobblemonItems.WISE_GLASSES)
entries.add(CobblemonItems.ZOOM_LENS)
}
private fun pokeballentries(displayContext: DisplayContext, entries: Entries) {
CobblemonItems.pokeBalls.forEach(entries::add)
}
private fun foodInjections(displayContext: DisplayContext): List<Item> = arrayListOf(
CobblemonItems.ROASTED_LEEK,
CobblemonItems.LEEK_AND_POTATO_STEW,
CobblemonItems.BRAISED_VIVICHOKE,
CobblemonItems.VIVICHOKE_DIP
)
private fun foodInjections(injector: Injector) {
injector.putLast(CobblemonItems.ROASTED_LEEK)
injector.putLast(CobblemonItems.LEEK_AND_POTATO_STEW)
injector.putLast(CobblemonItems.BRAISED_VIVICHOKE)
injector.putLast(CobblemonItems.VIVICHOKE_DIP)
}
private fun toolsAndUtilitiesInjections(injector: Injector) {
injector.putAfter(CobblemonItems.APRICORN_BOAT, Items.BAMBOO_CHEST_RAFT)
injector.putAfter(CobblemonItems.APRICORN_CHEST_BOAT, CobblemonItems.APRICORN_BOAT)
}
/**
* The abstract behaviour of injecting into existing [ItemGroup]s in specific positions.
* Each platform has to implement the behaviour.
*/
interface Injector {
/**
* Places the given [item] at the start of a creative tab.
*
* @param item The [ItemConvertible] being added at the start of a tab.
*/
fun putFirst(item: ItemConvertible)
/**
* Places the given [item] before the [target].
* If the [target] is not present behaves as [putLast].
*
* @param item The [ItemConvertible] being added before [target].
* @param target The [ItemConvertible] being targeted.
*/
fun putBefore(item: ItemConvertible, target: ItemConvertible)
/**
* Places the given [item] after the [target].
* If the [target] is not present behaves as [putLast].
*
* @param item The [ItemConvertible] being added after [target].
* @param target The [ItemConvertible] being targeted.
*/
fun putAfter(item: ItemConvertible, target: ItemConvertible)
/**
* Places the given [item] at the end of a creative tab.
*
* @param item The [ItemConvertible] being added at the end of a tab.
*/
fun putLast(item: ItemConvertible)
}
}
@@ -10,14 +10,17 @@ package com.cobblemon.mod.common.item.interactive
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
import com.cobblemon.mod.common.api.interaction.PokemonEntityInteraction
import com.cobblemon.mod.common.api.item.PokemonSelectingItem
import com.cobblemon.mod.common.api.pokemon.experience.CandyExperienceSource
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.item.CobblemonItem
import com.cobblemon.mod.common.item.interactive.CandyItem.Calculator
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.util.Hand
import net.minecraft.util.TypedActionResult
import net.minecraft.world.World
/**
* An experience candy item.
@@ -28,29 +31,45 @@ import net.minecraft.server.network.ServerPlayerEntity
* @author Licious
* @since May 5th, 2022
*/
class CandyItem(val calculator: Calculator) : CobblemonItem(Settings()), PokemonEntityInteraction {
override val accepted = setOf(PokemonEntityInteraction.Ownership.OWNER)
class CandyItem(val calculator: Calculator) : CobblemonItem(Settings()), PokemonSelectingItem {
override val bagItem = null
override fun processInteraction(player: ServerPlayerEntity, entity: PokemonEntity, stack: ItemStack): Boolean {
val pokemon = entity.pokemon
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack> {
if (user is ServerPlayerEntity) {
return use(user, user.getStackInHand(hand))
}
return TypedActionResult.success(user.getStackInHand(hand))
}
override fun applyToPokemon(player: ServerPlayerEntity, stack: ItemStack, pokemon: Pokemon): TypedActionResult<ItemStack>? {
val experience = this.calculator.calculate(player, pokemon)
CobblemonEvents.EXPERIENCE_CANDY_USE_PRE.postThen(
event = ExperienceCandyUseEvent.Pre(player, pokemon, this, experience, experience),
ifSucceeded = { preEvent ->
val finalExperience = preEvent.experienceYield
val source = CandyExperienceSource(player, stack)
val result = pokemon.addExperienceWithPlayer(player, source, finalExperience)
// We do this just so we can post the event once the item has been consumed if needed instead of repeating the even post
var returnValue = false
if (result.experienceAdded > 0) {
this.consumeItem(player, stack)
returnValue = true
event = ExperienceCandyUseEvent.Pre(player, pokemon, this, experience, experience),
ifSucceeded = { preEvent ->
val finalExperience = preEvent.experienceYield
val source = CandyExperienceSource(player, stack)
val result = pokemon.addExperienceWithPlayer(player, source, finalExperience)
// We do this just so we can post the event once the item has been consumed if needed instead of repeating the even post
var returnValue = false
if (result.experienceAdded > 0) {
if (!player.isCreative) {
stack.decrement(1)
}
returnValue = true
}
CobblemonEvents.EXPERIENCE_CANDY_USE_POST.post(ExperienceCandyUseEvent.Post(player, pokemon, this, result))
return if (returnValue)
TypedActionResult.success(stack)
else
TypedActionResult.fail(stack)
}
CobblemonEvents.EXPERIENCE_CANDY_USE_POST.post(ExperienceCandyUseEvent.Post(player, pokemon, this, result))
return returnValue
}
)
return false
return TypedActionResult.fail(stack)
}
override fun canUseOnPokemon(pokemon: Pokemon): Boolean {
return pokemon.isPlayerOwned()
}
/**
@@ -16,9 +16,11 @@ import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.item.CobblemonItem
import com.cobblemon.mod.common.item.battle.BagItem
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.giveOrDropItemStack
import kotlin.math.min
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.server.world.ServerWorld
import net.minecraft.sound.SoundCategory
@@ -59,6 +61,7 @@ class ElixirItem(val max: Boolean) : CobblemonItem(Settings()), PokemonSelecting
pokemon.moveSet.update()
if (!player.isCreative) {
stack.decrement(1)
player.giveOrDropItemStack(ItemStack(Items.GLASS_BOTTLE))
}
player.playSound(CobblemonSounds.MEDICINE_LIQUID_USE, SoundCategory.PLAYERS, 1F, 1F)
TypedActionResult.success(stack)
@@ -17,9 +17,11 @@ import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.item.CobblemonItem
import com.cobblemon.mod.common.item.battle.BagItem
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.giveOrDropItemStack
import kotlin.math.min
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.server.world.ServerWorld
import net.minecraft.sound.SoundCategory
@@ -49,6 +51,7 @@ class EtherItem(val max: Boolean): CobblemonItem(Settings()), PokemonAndMoveSele
player.playSound(CobblemonSounds.MEDICINE_LIQUID_USE, SoundCategory.PLAYERS, 1F, 1F)
if (!player.isCreative) {
stack.decrement(1)
player.giveOrDropItemStack(ItemStack(Items.GLASS_BOTTLE))
}
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.item.interactive
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
@@ -31,6 +32,10 @@ class HealPowderItem : CobblemonItem(Settings()), PokemonSelectingItem {
override fun getShowdownInput(actor: BattleActor, battlePokemon: BattlePokemon, data: String?) = "cure_status"
}
init {
Cobblemon.implementation.registerCompostable(this, .75F)
}
override fun canUseOnPokemon(pokemon: Pokemon) = pokemon.status != null && pokemon.currentHealth > 0
override fun applyToPokemon(
player: ServerPlayerEntity,
@@ -19,10 +19,12 @@ import com.cobblemon.mod.common.item.battle.BagItem
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.genericRuntime
import com.cobblemon.mod.common.util.giveOrDropItemStack
import com.cobblemon.mod.common.util.resolveInt
import java.lang.Integer.min
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.sound.SoundCategory
import net.minecraft.util.Hand
@@ -56,6 +58,7 @@ class PotionItem(val type: PotionType) : CobblemonItem(Settings()), PokemonSelec
player.playSound(CobblemonSounds.MEDICINE_SPRAY_USE, SoundCategory.PLAYERS, 1F, 1F)
if (!player.isCreative) {
stack.decrement(1)
player.giveOrDropItemStack(ItemStack(Items.GLASS_BOTTLE))
}
return TypedActionResult.success(stack)
}
@@ -17,8 +17,10 @@ import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.item.CobblemonItem
import com.cobblemon.mod.common.item.battle.BagItem
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.giveOrDropItemStack
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.sound.SoundCategory
import net.minecraft.util.Hand
@@ -50,6 +52,7 @@ class StatusCureItem(val itemName: String, vararg val status: Status) : Cobblemo
player.playSound(CobblemonSounds.MEDICINE_SPRAY_USE, SoundCategory.PLAYERS, 1F, 1F)
if (!player.isCreative) {
stack.decrement(1)
player.giveOrDropItemStack(ItemStack(Items.GLASS_BOTTLE))
}
TypedActionResult.success(stack)
} else {
@@ -10,9 +10,8 @@ package com.cobblemon.mod.common.loot
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.loot.LootManager
import net.minecraft.loot.LootPool
import net.minecraft.loot.LootTable
import net.minecraft.loot.LootTables
import net.minecraft.loot.entry.LootTableEntry
import net.minecraft.loot.provider.number.UniformLootNumberProvider
import net.minecraft.util.Identifier
@@ -27,9 +26,37 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
object LootInjector {
// cobblemon:injection/minecraft/chests/spawn_bonus_chest would target minecraft:chests/spawn_bonus_chest
private const val PREFIX = "injection/"
private val VILLAGE_HOUSE = cobblemonResource("injection/chests/village_house")
private val villageHouseLootTables = hashSetOf(
LootTables.VILLAGE_DESERT_HOUSE_CHEST,
LootTables.VILLAGE_PLAINS_CHEST,
LootTables.VILLAGE_SAVANNA_HOUSE_CHEST,
LootTables.VILLAGE_SNOWY_HOUSE_CHEST,
LootTables.VILLAGE_TAIGA_HOUSE_CHEST,
)
private val injections = hashSetOf(
LootTables.ABANDONED_MINESHAFT_CHEST,
LootTables.ANCIENT_CITY_CHEST,
LootTables.BASTION_BRIDGE_CHEST,
LootTables.BASTION_HOGLIN_STABLE_CHEST,
LootTables.BASTION_OTHER_CHEST,
LootTables.BASTION_TREASURE_CHEST,
LootTables.END_CITY_TREASURE_CHEST,
LootTables.IGLOO_CHEST_CHEST,
LootTables.JUNGLE_TEMPLE_CHEST,
LootTables.NETHER_BRIDGE_CHEST,
LootTables.PILLAGER_OUTPOST_CHEST,
LootTables.SHIPWRECK_SUPPLY_CHEST,
LootTables.SIMPLE_DUNGEON_CHEST,
LootTables.SPAWN_BONUS_CHEST,
LootTables.STRONGHOLD_CORRIDOR_CHEST,
LootTables.WOODLAND_MANSION_CHEST
).apply { addAll(villageHouseLootTables) }
/**
* Attempts to inject a Cobblemon injection loot table to a loot table being loaded.
* This will automatically query the existence of an injection.
@@ -38,18 +65,14 @@ object LootInjector {
* @param provider The job invoked if the injection is possible, this is what the platform needs to do to append the loot table.
* @return If the injection was made.
*/
fun attemptInjection(id: Identifier, lootManager: LootManager, provider: (LootPool.Builder) -> Unit): Boolean {
// Don't attempt to do things with our own pools, don't remove the namespace check as other mods may use similar solutions
if (id.namespace == Cobblemon.MODID && id.path.startsWith(PREFIX)) {
fun attemptInjection(id: Identifier, provider: (LootPool.Builder) -> Unit): Boolean {
if (!this.injections.contains(id)) {
return false
}
val resulting = this.convertToPotentialInjected(id)
// Defaults to LootTable.EMPTY instead of null
if (lootManager.getLootTable(resulting) != LootTable.EMPTY) {
provider(this.injectLootPool(resulting))
return true
}
return false
Cobblemon.LOGGER.debug("{}: Injected {} to {}", this::class.simpleName, resulting, id)
provider(this.injectLootPool(resulting))
return true
}
/**
@@ -58,7 +81,12 @@ object LootInjector {
* @param source The [Identifier] of the base loot table.
* @return The [Identifier] for the expected Cobblemon injection.
*/
private fun convertToPotentialInjected(source: Identifier): Identifier = cobblemonResource("$PREFIX${source.namespace}/${source.path}")
private fun convertToPotentialInjected(source: Identifier): Identifier {
if (this.villageHouseLootTables.contains(source)) {
return VILLAGE_HOUSE
}
return cobblemonResource("$PREFIX${source.path}")
}
/**
* Creates a loot pool builder with our injection.
@@ -0,0 +1,54 @@
/*
* 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
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
import java.util.EnumSet
/**
* Used to populate the player interaction menu
*
*
* @author Apion
* @since November 5th, 2023
*/
class PlayerInteractOptionsPacket(
val options: EnumSet<Options>,
val targetId: UUID,
val numericTargetId: Int,
val selectedPokemonId: UUID
) : NetworkPacket<PlayerInteractOptionsPacket> {
companion object {
val ID = cobblemonResource("player_interactions")
fun decode(buffer: PacketByteBuf) = PlayerInteractOptionsPacket(
buffer.readEnumSet(Options::class.java),
buffer.readUuid(),
buffer.readInt(),
buffer.readUuid()
)
}
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeEnumSet(options, Options::class.java)
buffer.writeUuid(targetId)
buffer.writeInt(numericTargetId)
buffer.writeUuid(selectedPokemonId)
}
enum class Options {
BATTLE,
SPECTATE_BATTLE,
TRADE
}
}
@@ -49,7 +49,11 @@ class BattleInitializePacket() : NetworkPacket<BattleInitializePacket> {
lateinit var side1: BattleSideDTO
lateinit var side2: BattleSideDTO
constructor(battle: PokemonBattle, allySide: BattleSide): this() {
/**
* @param battle The battle to initialize on the client
* @param allySide The [BattleSide] the client is on, null if the client is a spectator
*/
constructor(battle: PokemonBattle, allySide: BattleSide?): this() {
battleId = battle.battleId
battleFormat = battle.format
val sides = arrayOf(battle.side1, battle.side2).map { side ->
@@ -59,7 +63,9 @@ class BattleInitializePacket() : NetworkPacket<BattleInitializePacket> {
uuid = actor.uuid,
showdownId = actor.showdownId,
displayName = actor.getName(),
activePokemon = actor.activePokemon.map { it.battlePokemon?.let { pkm -> ActiveBattlePokemonDTO.fromPokemon(pkm, allySide == side) } },
activePokemon = actor.activePokemon.map { it.battlePokemon?.let {
pkm -> ActiveBattlePokemonDTO.fromPokemon(pkm, allySide == side)
} },
type = actor.type
)
}
@@ -0,0 +1,40 @@
/*
* 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.server
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
/**
* Sent from client to request a [com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket]
*
* @author Apion
* @since November 5th, 2023
*/
class RequestPlayerInteractionsPacket(
val targetId: UUID,
val targetNumericId: Int,
val pokemonId: UUID
) : NetworkPacket<RequestPlayerInteractionsPacket> {
companion object {
val ID = cobblemonResource("request_interactions")
fun decode(buffer: PacketByteBuf) = RequestPlayerInteractionsPacket(buffer.readUuid(), buffer.readInt(), buffer.readUuid())
}
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeUuid(targetId)
buffer.writeInt(targetNumericId)
buffer.writeUuid(pokemonId)
}
}
@@ -0,0 +1,26 @@
/*
* 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.server.battle
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
class RemoveSpectatorPacket(val battleId: UUID) : NetworkPacket<RemoveSpectatorPacket> {
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeUuid(battleId)
}
companion object {
val ID = cobblemonResource("remove_spectator")
fun decode(buffer: PacketByteBuf) = RemoveSpectatorPacket(buffer.readUuid())
}
}
@@ -0,0 +1,26 @@
/*
* 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.server.battle
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.PacketByteBuf
import java.util.UUID
class SpectateBattlePacket(val targetedEntityId: UUID) : NetworkPacket<SpectateBattlePacket> {
override val id = ID
override fun encode(buffer: PacketByteBuf) {
buffer.writeUuid(targetedEntityId)
}
companion object {
val ID = cobblemonResource("battle_spectate")
fun decode(buffer: PacketByteBuf) = SpectateBattlePacket(buffer.readUuid())
}
}
@@ -0,0 +1,40 @@
/*
* 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.serverhandling
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import java.util.EnumSet
object RequestInteractionsHandler : ServerNetworkPacketHandler<RequestPlayerInteractionsPacket> {
override fun handle(
packet: RequestPlayerInteractionsPacket,
server: MinecraftServer,
player: ServerPlayerEntity
) {
//We could potentially check if the targeted player has pokemon here
val options = EnumSet.of(PlayerInteractOptionsPacket.Options.TRADE)
val isTargetBattling = BattleRegistry.getBattleByParticipatingPlayerId(packet.targetId) != null
if (isTargetBattling and Cobblemon.config.allowSpectating) {
options.add(PlayerInteractOptionsPacket.Options.SPECTATE_BATTLE)
}
else {
options.add(PlayerInteractOptionsPacket.Options.BATTLE)
}
PlayerInteractOptionsPacket(options, packet.targetId, packet.targetNumericId, packet.pokemonId).sendToPlayer(player)
}
}
@@ -0,0 +1,26 @@
/*
* 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.serverhandling.battle
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
object RemoveSpectatorHandler : ServerNetworkPacketHandler<RemoveSpectatorPacket> {
override fun handle(
packet: RemoveSpectatorPacket,
server: MinecraftServer,
player: ServerPlayerEntity
) {
BattleRegistry.getBattle(packet.battleId)?.spectators?.remove(player.uuid)
}
}
@@ -0,0 +1,40 @@
/*
* 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.serverhandling.battle
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.net.messages.client.battle.BattleInitializePacket
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.network.ServerPlayerEntity
import org.apache.logging.log4j.LogManager
object SpectateBattleHandler : ServerNetworkPacketHandler<SpectateBattlePacket> {
val LOGGER = LogManager.getLogger()
override fun handle(
packet: SpectateBattlePacket,
server: MinecraftServer,
player: ServerPlayerEntity
) {
val battle = BattleRegistry.getBattleByParticipatingPlayerId(packet.targetedEntityId)
if ((battle != null) and Cobblemon.config.allowSpectating) {
battle!!.spectators.add(player.uuid)
player.sendPacket(BattleInitializePacket(battle, null))
player.sendPacket(BattleMessagePacket(battle.chatLog))
}
else {
LOGGER.error("Battle of player id ${packet.targetedEntityId} not found (${player.uuid} tried spectating)")
}
}
}
@@ -36,7 +36,7 @@ object SendOutPokemonHandler : ServerNetworkPacketHandler<SendOutPokemonPacket>
val trace = player.traceBlockCollision(maxDistance = 15F)
if (trace != null && !player.world.getBlockState(trace.blockPos.up()).isSolid) {
val position = Vec3d(trace.location.x, trace.blockPos.up().toVec3d().y, trace.location.z)
pokemon.sendOutWithAnimation(player, player.serverWorld, position)
pokemon.sendOutWithAnimation(player, player.serverWorld, position)
}
} else {
val entity = state.entity
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.pokemon.evolution.progress
import com.cobblemon.mod.common.api.pokemon.evolution.progress.EvolutionProgress
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.evolution.requirements.BattleCriticalHitsRequirement
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.JsonObject
import net.minecraft.nbt.NbtCompound
import net.minecraft.util.Identifier
class LastBattleCriticalHitsEvolutionProgress : EvolutionProgress<LastBattleCriticalHitsEvolutionProgress.Progress> {
private var progress = Progress(0)
override fun id(): Identifier = ID
override fun currentProgress(): Progress = this.progress
override fun updateProgress(progress: Progress) {
this.progress = progress
}
override fun reset() {
this.updateProgress(Progress(0))
}
override fun shouldKeep(pokemon: Pokemon): Boolean = supports(pokemon)
override fun loadFromNBT(nbt: NbtCompound) {
val amount = nbt.getInt(AMOUNT)
this.updateProgress(Progress(amount))
}
override fun saveToNBT(): NbtCompound = NbtCompound().apply { putInt(AMOUNT, currentProgress().amount) }
override fun loadFromJson(json: JsonObject) {
val amount = json.get(AMOUNT).asInt
this.updateProgress(Progress(amount))
}
override fun saveToJson(): JsonObject = JsonObject().apply { addProperty(AMOUNT, currentProgress().amount) }
data class Progress(val amount: Int)
companion object {
val ID = cobblemonResource(BattleCriticalHitsRequirement.ADAPTER_VARIANT)
private const val AMOUNT = "amount"
fun supports(pokemon: Pokemon): Boolean {
return pokemon.form.evolutions.any { evolution ->
evolution.requirements.any { requirement ->
requirement is BattleCriticalHitsRequirement
}
}
}
}
}
@@ -9,9 +9,8 @@
package com.cobblemon.mod.common.pokemon.evolution.requirements
import com.cobblemon.mod.common.api.pokemon.evolution.requirement.EvolutionRequirement
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.pokemon.Pokemon
import kotlin.jvm.optionals.getOrNull
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
/**
* An [EvolutionRequirement] for a certain amount of critical hits in a single battle.
@@ -21,6 +20,7 @@ import kotlin.jvm.optionals.getOrNull
* @author Licious
* @since October 2nd, 2022
*/
@Suppress("unused", "CanBePrimaryConstructorProperty")
class BattleCriticalHitsRequirement(amount: Int) : EvolutionRequirement {
constructor() : this(0)
@@ -30,20 +30,10 @@ class BattleCriticalHitsRequirement(amount: Int) : EvolutionRequirement {
*/
val amount = amount
@OptIn(ExperimentalStdlibApi::class)
override fun check(pokemon: Pokemon): Boolean {
val pokemonEntity = pokemon.entity ?: return false
val battleId = pokemonEntity.battleId.get().getOrNull() ?: return false
val battle = BattleRegistry.getBattle(battleId) ?: return false
battle.actors.forEach { actor ->
actor.pokemonList.forEach { battlePokemon ->
if (battlePokemon.effectedPokemon.uuid == pokemon.uuid) {
return battlePokemon.criticalHits >= this.amount
}
}
}
return false
}
override fun check(pokemon: Pokemon): Boolean = pokemon.evolutionProxy.current()
.progress()
.filterIsInstance<LastBattleCriticalHitsEvolutionProgress>()
.any { progress -> progress.currentProgress().amount >= this.amount }
companion object {
const val ADAPTER_VARIANT = "battle_critical_hits"
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.pokemon.helditem.HeldItemManager
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.battleLang
@@ -28,6 +29,7 @@ import java.util.function.Function
* @author Licious
* @since December 30th, 2022
*/
@Suppress("unused")
object CobblemonHeldItemManager : BaseCobblemonHeldItemManager() {
/**
@@ -73,8 +75,8 @@ object CobblemonHeldItemManager : BaseCobblemonHeldItemManager() {
}
override fun handleStartInstruction(pokemon: BattlePokemon, battle: PokemonBattle, battleMessage: BattleMessage) {
val consumeHeldItems = Cobblemon.config.consumeHeldItems
val itemID = battleMessage.effectAt(1)?.id ?: return
val consumeHeldItems = this.shouldConsumeItem(pokemon, battle, itemID)
if (battleMessage.hasOptionalArgument("silent")) {
if (consumeHeldItems) {
this.take(pokemon, itemID)
@@ -137,6 +139,16 @@ object CobblemonHeldItemManager : BaseCobblemonHeldItemManager() {
battle.broadcastChatMessage(text)
}
override fun shouldConsumeItem(pokemon: BattlePokemon, battle: PokemonBattle, showdownId: String): Boolean {
// In 3rd party and the future battles might have multiple types, give it a priority from pvp down to wild.
val tag = when {
battle.isPvP -> CobblemonItemTags.CONSUMED_IN_PVP_BATTLE
battle.isPvN -> CobblemonItemTags.CONSUMED_IN_NPC_BATTLE
else -> CobblemonItemTags.CONSUMED_IN_WILD_BATTLE
}
return pokemon.effectedPokemon.heldItem().isIn(tag)
}
/**
* Registers a custom mapping from [Item] to showdown ID string.
*
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.data.DataRegistry
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.api.pokemon.Natures
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.api.pokemon.status.Statuses
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.types.ElementalTypes
@@ -146,6 +147,8 @@ internal object PropertiesCompletionProvider : DataRegistry {
this.inject(setOf("${statName}_iv"), setOf("0", IVs.MAX_VALUE.toString()))
this.inject(setOf("${statName}_ev"), setOf("0", EVs.MAX_STAT_VALUE.toString()))
}
this.inject(setOf("status"), Statuses.getPersistentStatuses().map { if (it.name.namespace == Cobblemon.MODID) it.name.path else it.name.toString() })
}
private fun addCustom() {
@@ -123,13 +123,15 @@ object DataKeys {
const val CAN_BE_MILKED = "milkable"
const val HAS_BEEN_SHEARED = "sheared"
// Variants
const val IS_MOOSHTANK = "mooshtank"
// Persistent Data
const val POKEMON_PERSISTENT_DATA = "PersistentData"
// Item Tooltips
const val HIDE_TOOLTIP = "HideTooltip"
// Shoulder Mount
const val SHOULDER_UUID = "shoulder_uuid"
const val SHOULDER_SPECIES = "shoulder_species"
@@ -0,0 +1,9 @@
{
"sources": [
{
"type": "directory",
"source": "entity/signs",
"prefix": "entity/signs/"
}
]
}
@@ -4,7 +4,7 @@
"animation.poke_ball.open": {
"animation_length": 0.5,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": [-5, 0, 0],
@@ -21,46 +21,119 @@
"0.2083": [-105, 0, 0],
"0.4167": [-70, 0, 0]
}
},
"ball": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": [15, 0, 0],
"0.1667": [-10, 0, 0],
"0.3333": [22.5, 0, 0]
},
"position": {
"0.0833": [0, 0, 0],
"0.125": [0, -0.1, 0],
"0.1667": [0, 0.1, 0],
"0.2083": [0, 0, 0]
}
}
}
},
"animation.poke_ball.open_idle": {
"loop": true,
"bones": {
"base": {
"bottom": {
"rotation": [35, 0, 0]
},
"lid": {
"rotation": [-70, 0, 0]
"rotation": ["-70+math.sin(q.anim_time*90*10)*0.6+math.sin(q.anim_time*90*1)*3", 0, 0]
},
"ball": {
"rotation": ["22.5-math.sin(q.anim_time*90*10)*0.4-math.sin(q.anim_time*90*1)*2", 0, "0-math.sin(q.anim_time*90*2)*0.5"],
"position": [0, "math.sin(q.anim_time*90*2-60)*0.1", 0]
}
}
},
"animation.poke_ball.shut": {
"animation_length": 0.5,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [35, 0, 0],
"0.0833": [40, 0, 0],
"0.1667": [-5, 0, 0],
"0.0": {
"post": [35, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [40, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": [0, 0, 0]
}
},
"lid": {
"rotation": {
"0.0": [-70, 0, 0],
"0.0833": [-80, 0, 0],
"0.1667": [2.5, 0, 0],
"0.0": {
"post": [-70, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [-80, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": [0, 0, 0]
}
},
"ball": {
"rotation": {
"0.0": {
"post": [22.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, 0, -2.5],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [0, 0, 2.5],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": [0, 0, 0],
"0.1667": [0, 0, 0],
"0.2083": [0, -0.1, 0],
"0.25": [0, 0.1, 0],
"0.2917": [0, -0.1, 0],
"0.3333": [0, 0.1, 0],
"0.375": [0, 0, 0]
}
}
}
},
"animation.poke_ball.shut_idle": {
"loop": true,
"bones": {
"base": {
"rotation": [0, 0, 0]
"bottom": {
"rotation": ["math.sin(q.anim_time*90*0.5)*0.4", 0, "math.cos(q.anim_time*90*0.5)*0.2"]
},
"lid": {
"rotation": [0, 0, 0]
@@ -70,40 +143,108 @@
"animation.poke_ball.bounce": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [0, 0, 5],
"0.0417": [0, 0, -2.5],
"0.125": [0, 0, -5],
"0.2083": [0, 0, -7.5],
"0.2917": [0, 0, -10],
"0.4583": [0, 0, -10],
"0.5": [0, 0, 0],
"0.5833": [0, 0, 5],
"0.6667": [0, 0, 7.5],
"0.75": [0, 0, 0],
"0.7917": [0, 0, -2.5],
"0.8333": [0, 0, 0]
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0417": {
"post": [5.00232, -2.48336, 3.67327],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [0, 0, -2.5],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 1.6, -9],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [0, 2.5, -9],
"lerp_mode": "catmullrom"
},
"0.5417": {
"post": [0, -2.1, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [0, -3.1, 5],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, -2, 2.1],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, -1.9, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [0, -0.3, 0.6],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": [0, -0.5, 0],
"0.0417": [0, 1.5, 0],
"0.125": [0, 3.75, 0],
"0.2083": [0, 3, 0],
"0.2917": [0, 2.75, 0],
"0.375": [0, 1.19, 0],
"0.4583": [0, -0.25, 0],
"0.5833": [0, 1, 0],
"0.6667": [0, 0.67, 0],
"0.75": [0, 0, 0]
"0.0417": [0, 0, 0],
"0.0833": [0, -0.5, 0],
"0.125": [0, 1.5, 0],
"0.1667": [0, 3.25, 0],
"0.25": {
"pre": [0, 3.5, 0],
"post": [0, 3.5, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [0, 2.75, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [0, 1.19, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, -0.25, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 0.67, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [0, 0.2, 0],
"lerp_mode": "catmullrom"
},
"1.0": [0, 0, 0]
}
},
"lid": {
"rotation": [0, 0, 0],
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, 0],
"0.4583": [0, 0, 0],
"0.5417": [2.5, 0, 0],
"0.6667": [0, 0, 0],
"0.8333": [0, 0, 0]
},
"position": {
"0.0": [0, -0.25, 0],
"0.0417": [0, -0.5, 0],
"0.1667": [0, 0, 0]
"0.0": [0, 0, 0],
"0.0417": [0, -0.25, 0],
"0.0833": [0, -0.5, 0],
"0.2083": [0, 0, 0]
}
}
}
@@ -111,14 +252,11 @@
"animation.poke_ball.bob1": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [2.46271, -0.86717, 4.92442],
"0.0417": [15, 0, 0],
"0.1667": [0, 0, -15],
"0.2917": [-10, 0, 0],
"0.375": [0, 0, 5],
"0.5": [0, 0, 0]
"0.0": ["math.sin(q.anim_time*90*12)*15", 0, "-math.sin(q.anim_time*90*8)*10"],
"0.6667": ["math.sin(q.anim_time*90*15)*2", 0, "-math.sin(q.anim_time*90*8)*2"],
"0.875": [0, 0, 0]
}
}
}
@@ -126,14 +264,11 @@
"animation.poke_ball.bob2": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [2.46271, 0.86717, -4.92442],
"0.0417": [15, 0, 0],
"0.1667": [0, 0, 15],
"0.2917": [-10, 0, 0],
"0.375": [0, 0, -5],
"0.5": [0, 0, 0]
"0.0": ["math.sin(q.anim_time*90*12)*15", 0, "math.sin(q.anim_time*90*8)*10"],
"0.6667": ["math.sin(q.anim_time*90*15)*2", 0, "math.sin(q.anim_time*90*8)*2"],
"0.875": [0, 0, 0]
}
}
}
@@ -141,22 +276,17 @@
"animation.poke_ball.bob3": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, 7.5],
"0.1667": [0, 0, -12.5],
"0.3333": [0, 0, 7.5],
"0.4167": [0, 0, 0]
"0.0833": ["math.cos(q.anim_time*90*10-60)*1", "math.sin(q.anim_time*90*10-60)*2", "-math.sin(q.anim_time*90*10-60)*14"],
"0.5": [0, "math.sin(q.anim_time*90*10-60)*1", "-math.sin(q.anim_time*90*10-60)*6"],
"0.75": [0, "math.sin(q.anim_time*90*10-60)*1", "-math.sin(q.anim_time*90*10-60)*1"],
"0.9583": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.0833": [-1, 0, 0],
"0.125": [-1.5, 0, 0],
"0.1667": [-1, 0, 0],
"0.25": [1, 0, 0],
"0.2917": [1.25, 0, 0],
"0.375": [0, 0, 0]
"0.0": ["-math.sin(q.anim_time*90*10)*0.5", 0, 0],
"0.6667": [0, 0, 0]
}
}
}
@@ -164,22 +294,17 @@
"animation.poke_ball.bob4": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, -7.5],
"0.1667": [0, 0, 12.5],
"0.3333": [0, 0, -7.5],
"0.4167": [0, 0, 0]
"0.0833": ["math.cos(q.anim_time*90*10-60)*1", "-math.sin(q.anim_time*90*10-60)*2", "math.sin(q.anim_time*90*10-60)*14"],
"0.5": [0, "-math.sin(q.anim_time*90*10-60)*1", "math.sin(q.anim_time*90*10-60)*6"],
"0.75": [0, "-math.sin(q.anim_time*90*10-60)*1", "math.sin(q.anim_time*90*10-60)*1"],
"0.9583": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.0833": [1, 0, 0],
"0.125": [1.5, 0, 0],
"0.1667": [1, 0, 0],
"0.25": [-1, 0, 0],
"0.2917": [-1.25, 0, 0],
"0.375": [0, 0, 0]
"0.0": ["math.sin(q.anim_time*90*10)*0.5", 0, 0],
"0.6667": [0, 0, 0]
}
}
}
@@ -187,24 +312,76 @@
"animation.poke_ball.bob5": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [10, 0, 0],
"0.0833": [-2.5, 0, 0],
"0.1667": [-5, 0, 0],
"0.25": [-7.5, 0, 0],
"0.3333": [-15, 0, 0],
"0.375": [0, 0, 0],
"0.4583": [5, 0, 0],
"0.5": [0, 0, 0]
"0.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [10.00933, 2.462, 0.43439],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [-7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [-14.98637, 0.64686, 2.41492],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [4.99527, 0.21782, -2.4905],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [-1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": [0, -0.5, 0],
"0.0833": [0, 4, 0],
"0.1667": [0, 4.5, 0],
"0.25": [0, 4, 0],
"0.3333": [0, 1.75, 0],
"0.375": [0, -0.5, 0]
"0.0833": [0, 0, 0],
"0.1667": {
"pre": [0, 3, 0],
"post": [0, 3, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 4.5, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [0, 4, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [0, 1.75, 0],
"lerp_mode": "catmullrom"
},
"0.4583": [0, 0, 0],
"0.5": [0, -0.1, 0],
"0.5417": [0, 0.1, 0],
"0.5833": [0, -0.1, 0],
"0.625": [0, 0.1, 0],
"0.6667": [0, -0.1, 0],
"0.75": [0, 0, 0]
}
}
}
@@ -212,24 +389,86 @@
"animation.poke_ball.bob6": {
"animation_length": 1,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [0, 0, -10],
"0.0833": [0, 0, -2.5],
"0.1667": [0, 0, 10],
"0.25": [0, 0, 15],
"0.3333": [0, 0, 15],
"0.375": [0, 0, 0],
"0.4583": [0, 0, -7.5],
"0.5417": [0, 0, 0]
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0417": {
"post": [0, 0, -11.1],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [0, 0, -2.5],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0, 10],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [0, 0, 15],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [0, 0, 13.2],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [0, 0, 1.4],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [0, 0, -5.5],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [0, 0, 0.3],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, 0, -0.5],
"lerp_mode": "catmullrom"
},
"0.9583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": [0, -0.5, 0],
"0.0833": [0, 4, 0],
"0.1667": [0, 4.5, 0],
"0.25": [0, 4, 0],
"0.3333": [0, 1.75, 0],
"0.375": [0, -0.5, 0]
"0.0833": [0, 0, 0],
"0.1667": {
"pre": [0, 3, 0],
"post": [0, 3, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 4.5, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [0, 4, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [0, 1.75, 0],
"lerp_mode": "catmullrom"
},
"0.4583": [0, 0, 0],
"0.5": [0, -0.1, 0],
"0.5417": [0, 0.1, 0],
"0.5833": [0, -0.1, 0],
"0.625": [0, 0.1, 0],
"0.6667": [0, -0.1, 0],
"0.75": [0, 0, 0]
}
},
"ball": {
"rotation": {
"0.0": [0, 0, 0],
"0.375": [0, 4, 0],
"0.5833": [0, 0, 0]
}
}
}
@@ -237,45 +476,221 @@
"animation.poke_ball.critical": {
"animation_length": 1,
"bones": {
"base": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0.5, 0, 0],
"0.0833": [-0.5, 0, 0],
"0.125": [0, 0, 0],
"0.1667": [-0.75, 0, 0],
"0.2083": [0.5, 0, 0],
"0.25": [0, 0, 0]
}
}
}
},
"animation.poke_ball.capture": {
"animation_length": 0.5,
"bones": {
"base": {
"bottom": {
"rotation": {
"0.0": [-2.5, 0, 0],
"0.0417": [5, 0, 0],
"0.0833": [0, 0, 0]
"0.0": [0, 0, 0],
"0.0417": [0, "math.sin(q.anim_time*90*10)*3", "math.sin(q.anim_time*90*30-90)*2"],
"0.7083": [0, "math.sin(q.anim_time*90*10)*1", "math.sin(q.anim_time*90*10-90)*0.4"],
"0.9167": [0, 0, 0]
},
"position": [0, 0, 0]
},
"lid": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [2.5, 0, 0],
"0.0833": [0, 0, 0]
"position": {
"0.0": ["math.sin(q.anim_time*90*40)*1.5", "math.sin(q.anim_time*90*80)*0.2", 0],
"0.4167": ["math.sin(q.anim_time*90*20)*0.3", "math.sin(q.anim_time*90*40)*0.1", 0],
"0.75": [0, 0, 0]
}
}
}
},
"animation.poke_ball.throw": {
"loop": true,
"animation_length": 4,
"bones": {
"base": {
"rotation": ["(q.anim_time - 0.38) * 720", 0, 0],
"position": [0, "4 + Math.Sin((q.anim_time + 0.5) * 720) * 4", "Math.Sin((q.anim_time - 0.1275) * 720) * -4"]
"bottom": {
"rotation": ["-(q.anim_time - 0.38) * 720", 0, 0],
"position": [0, "4 + Math.Sin((q.anim_time + 0.5) * 720) * 4", "Math.Sin((q.anim_time - 0.1275) * 720) * 4"]
},
"ball": {
"rotation": [0, 0, "-math.sin(q.anim_time*90*1)*10-math.sin(q.anim_time*90*20)*3"]
}
}
},
"animation.poke_ball.throw_horizontal": {
"loop": true,
"animation_length": 2,
"bones": {
"bottom": {
"rotation": [0, "(q.anim_time - 0.38) * 720", 0]
},
"ball": {
"rotation": [0, "math.sin(q.anim_time*90*1)*8", "math.sin(q.anim_time*90*2-60)*8+math.sin(q.anim_time*90*8)*2"],
"position": ["-math.sin(q.anim_time*90*2)*1", "math.sin(q.anim_time*90*8)*0.1", 0]
}
}
},
"animation.poke_ball.throw_beast": {
"loop": true,
"animation_length": 4,
"bones": {
"bottom": {
"scale": [1, 1, "1+math.sin(q.anim_time*90*1)*0.1"]
},
"ball": {
"rotation": [0, 0, "(q.anim_time - 0.38) * 720"],
"position": ["math.sin(q.anim_time*90*1)*1", "math.sin(q.anim_time*90*2)*0.5", "math.sin(q.anim_time*90*20)*0.1"],
"scale": 1
}
}
},
"animation.poke_ball.throw_ace": {
"loop": true,
"animation_length": 2,
"bones": {
"bottom": {
"rotation": [0, "(q.anim_time - 0.38) * (1440+720)", 0],
"scale": ["1.1+math.sin(q.anim_time*90*2)*0.1", 0.9, "1.1+math.sin(q.anim_time*90*2)*0.1"]
},
"ball": {
"rotation": [0, "math.sin(q.anim_time*90*1)*8", "math.sin(q.anim_time*90*2-60)*8+math.sin(q.anim_time*90*8)*2"],
"position": ["-math.sin(q.anim_time*90*2)*1", "math.cos(q.anim_time*90*2)*0.1", 0]
}
}
},
"animation.poke_ball.break": {
"animation_length": 1,
"bones": {
"ball": {
"rotation": {
"0.0": [0, 0, 0],
"0.3333": [0, -15, 0],
"0.4583": [0, -15, 0]
}
},
"bottom": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0417": {
"post": [10.00933, 2.462, 0.43439],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [1.2, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [-2.18637, 0.64686, 2.41492],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [-0.86335, -0.04043, -0.15093],
"lerp_mode": "catmullrom"
},
"0.5417": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [0.5, 0.00297, 0.01109],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0.2, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, 0],
"0.0833": {
"pre": [0, 1, 0],
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [0, 1.7, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0.55, 0],
"lerp_mode": "catmullrom"
},
"0.2917": [0, 0, 0],
"0.3333": [0, -0.1, 0],
"0.375": [0, 0.1, 0],
"0.4167": [0, -0.1, 0],
"0.4583": [0, 0, 0]
}
},
"lid": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [2, 0, 0],
"0.125": [-163, 0, -9],
"0.2917": [-142.06462, -15.59097, 16.16746],
"0.375": {
"pre": [-173.66608, -1.87837, 16.30697],
"post": [-173.66608, -1.87837, 16.30697],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-150.60076, -1.11104, 19.38321],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [-153.28391, -1.57451, 20.44204],
"lerp_mode": "catmullrom"
},
"0.9583": [-154.20104, -1.23272, 20.47764]
},
"position": {
"0.0417": [0, 0, 0],
"0.0833": [0, 0, 0],
"0.1667": [0, 0, 0],
"0.2917": [0, -0.3, 0.2]
}
}
}
},
"animation.poke_ball.capture": {
"animation_length": 0.75,
"bones": {
"bottom": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": ["-2+math.sin(q.anim_time*90*2)*10", 0, 0],
"0.0833": ["1.5+math.sin(q.anim_time*90*16)*2", 0, 0],
"0.2917": ["-0.2+math.sin(q.anim_time*90*6)*0.2", 0, 0],
"0.4583": [0, 0, 0]
},
"position": [0, 0, 0]
},
"lid": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0417": {
"post": [3.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [0.2, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [0.1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
}
}
@@ -16,8 +16,20 @@
"pivot": [0, 0, 0]
},
{
"name": "base",
"name": "ball",
"parent": "poke_ball",
"pivot": [0, 4, 0],
"locators": {
"bottom_particles": {
"offset": [0, 0, 0],
"rotation": [180, 0, 0]
},
"center_particles": [0, 4, 0]
}
},
{
"name": "bottom",
"parent": "ball",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-4, 0, -4], "size": [8, 4, 8], "inflate": 0.25, "uv": [32, 20]},
@@ -26,16 +38,13 @@
},
{
"name": "lid",
"parent": "base",
"parent": "bottom",
"pivot": [0, 4, 4],
"cubes": [
{"origin": [-4, 4, -4], "size": [8, 4, 8], "uv": [0, 0]},
{"origin": [-1, 3, -4.255], "size": [2, 2, 0], "uv": [0, 0]},
{"origin": [-4, 4, -4], "size": [8, 4, 8], "inflate": 0.26, "uv": [0, 20]}
],
"locators": {
"beam": [0, 0.5, 0]
}
]
}
]
}
@@ -3,6 +3,7 @@
"animations": {
"animation.rattata.ground_idle": {
"loop": true,
"animation_length": 21.375,
"bones": {
"body": {
"rotation": ["math.sin(q.anim_time*90*8)*0.2", 0, 0],
@@ -15,39 +16,36 @@
"whisker_right": {
"rotation": [0, "math.sin(q.anim_time*90*8*2)*4", 0]
},
"whisker_left": {
"rotation": [0, "-math.sin(q.anim_time*90*8*2)*4", 0]
},
"ear_right": {
"rotation": [0, "math.sin(q.anim_time*90*4*2)*2", 0]
},
"ear_left": {
"rotation": [0, "-math.sin(q.anim_time*90*4*2)*2", 0]
},
"tail": {
"rotation": ["45-math.sin(q.anim_time*90*8*2)*2", 0, 0]
"rotation": ["37.5-math.sin(q.anim_time*90*8*2)*2", 0, 0]
},
"tail2": {
"rotation": ["15-math.sin(q.anim_time*90*8*2)*2", 0, 0]
"rotation": ["45-math.sin(q.anim_time*90*8*2)*2", 0, 0]
},
"leg_front_right": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.01,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"leg_front_left": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.01,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.02,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"leg_back_right": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.01,-0.025,0.025)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"tail4": {
"rotation": [15, 0, 0]
},
"tail3": {
"rotation": [20, 0, 0]
},
"leg_front_left": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.02,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"leg_back_left": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.01,-0.025,0.025)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"tail3": {
"rotation": [15, 0, 0]
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
}
}
},
@@ -76,14 +74,6 @@
],
"position": [0, 0, 0]
},
"leg_front_left": {
"rotation": [
"math.clamp(math.sin(-q.anim_time*90*4*1)*40,-50,0)+math.clamp(math.sin(q.anim_time*90*4*1)*40,-50,0)+math.clamp(math.sin(-q.anim_time*90*4*2)*50,0,40)",
0,
0
],
"position": [0, 0, 0]
},
"leg_back_right": {
"rotation": ["math.clamp(math.sin(q.anim_time*90*4*2)*40,0,50)-math.clamp(math.sin(-q.anim_time*90*4*2)*40,0,50)", 0, 0],
"position": [
@@ -92,31 +82,33 @@
"math.clamp(math.sin(q.anim_time*90*4*2-30)*0.5,0,2)-math.clamp(math.sin(q.anim_time*90*4*2-30+180)*0.5,0,2)"
]
},
"whisker_right": {
"rotation": [0, "15+math.sin(q.anim_time*90*4*2)*8", 0]
},
"ear_right": {
"rotation": [0, "15+math.sin(q.anim_time*90*4*2)*8", 0]
},
"tail2": {
"rotation": [15, 0, 0]
},
"tail4": {
"rotation": [15, 0, 0]
},
"leg_front_left": {
"rotation": [
"math.clamp(math.sin(-q.anim_time*90*4*1)*40,-50,0)+math.clamp(math.sin(q.anim_time*90*4*1)*40,-50,0)+math.clamp(math.sin(-q.anim_time*90*4*2)*50,0,40)",
0,
0
],
"position": [0, 0, 0]
},
"leg_back_left": {
"rotation": ["math.clamp(math.sin(q.anim_time*90*4*2+20)*40,0,50)-math.clamp(math.sin(-q.anim_time*90*4*2-20)*40,0,50)", 0, 0],
"rotation": ["math.clamp(math.sin(q.anim_time*90*4*2)*40,0,50)-math.clamp(math.sin(-q.anim_time*90*4*2)*40,0,50)", 0, 0],
"position": [
0,
"-math.clamp(math.sin(q.anim_time*90*4*2)*1,0,2)-math.clamp(math.sin(-q.anim_time*90*4*2)*0.8,0,2)",
"math.clamp(math.sin(q.anim_time*90*4*2-30)*0.5,0,2)-math.clamp(math.sin(q.anim_time*90*4*2-30+180)*0.5,0,2)"
]
},
"whisker_right": {
"rotation": [0, "15+math.sin(q.anim_time*90*4*2)*8", 0]
},
"whisker_left": {
"rotation": [0, "-15-math.sin(q.anim_time*90*4*2)*8", 0]
},
"ear_right": {
"rotation": [0, "15+math.sin(q.anim_time*90*4*2)*8", 0]
},
"ear_left": {
"rotation": [0, "-15-math.sin(q.anim_time*90*4*2)*8", 0]
},
"tail2": {
"rotation": [15, 0, 0]
},
"tail3": {
"rotation": [15, 0, 0]
}
}
},
@@ -125,23 +117,17 @@
"bones": {
"body": {
"rotation": [-3.75, 0, 0],
"position": [0, -2.1, 0]
"position": [0, -3.1, 0]
},
"head": {
"rotation": ["14.25-math.sin(q.anim_time*90*2)*1", -15.5, 2.5]
"rotation": ["11.75-math.sin(q.anim_time*90*2)*1", -15.5, 2.5]
},
"whisker_right": {
"rotation": [0, "20.25+math.sin(q.anim_time*90*2-40)*5", 0]
},
"whisker_left": {
"rotation": [0, "-7.5-math.sin(q.anim_time*90*2-40)*6", 0]
},
"ear_right": {
"rotation": [0, "35.5+math.sin(q.anim_time*90*2-40)*4", 0]
},
"ear_left": {
"rotation": [0, "-20.5-math.sin(q.anim_time*90*2-40)*5", 0]
},
"eyelid_right": {
"position": [-0.1, 0, 0]
},
@@ -155,27 +141,31 @@
"tail2": {
"rotation": ["11.25+math.sin(q.anim_time*90*2-40)*2", "28.5-math.sin(q.anim_time*90*2-80)*3", 5.5]
},
"tail3": {
"tail4": {
"rotation": ["5-math.sin(q.anim_time*90*2-80)*2", "35.75-math.sin(q.anim_time*90*2-120)*3", 3]
},
"leg_front_right": {
"rotation": [-72.5, 4.25, 10.75],
"position": [0, -0.75, 0]
},
"leg_front_left": {
"rotation": [-69.5, 10, -5.5],
"rotation": [-81.82706, 13.00814, 2.94613],
"position": [0, -0.75, 0]
},
"leg_back_right": {
"rotation": [83.5, 8.5, -2.5],
"position": [0, -0.5, 0]
},
"leg_back_left": {
"rotation": [80.75, 7.5, -15],
"rotation": [65.81451, -6.32173, 19.33562],
"position": [0, -0.5, 0]
},
"jaw": {
"rotation": ["5+math.sin(q.anim_time*90*2)*4", 0, 0]
},
"leg_front_left": {
"rotation": [-65.929, -37.44427, -4.88648]
},
"leg_back_right2": {
"rotation": [5, 0, 0]
},
"leg_back_left": {
"rotation": [58.31451, 6.32173, -19.33562]
},
"leg_back_left2": {
"rotation": [5, 0, 0]
}
}
},
@@ -233,19 +223,6 @@
"1.3333": [0, 57.5, 0]
}
},
"whisker_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [0, 47.5, 0],
"0.2917": [0, -17.5, 0],
"0.6667": [0, -17.5, 0],
"0.8333": [23.28697, -8.33702, -47.37353],
"1.2083": [23.28697, -8.33702, -47.37353],
"1.25": [0, -17.5, 0],
"1.2917": [0, 10, 0],
"1.5": [0, -22.5, 0]
}
},
"ear_right": {
"rotation": {
"0.0": [0, 0, 0],
@@ -257,14 +234,6 @@
"1.3333": [42.37797, -19.10791, 71.77865]
}
},
"ear_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": [0, 55, 0],
"0.3333": [0, 5, 0],
"1.1667": [0, 5, 0]
}
},
"tail": {
"rotation": {
"0.0": [37.5, 0, 0],
@@ -301,7 +270,7 @@
"1.8333": [0, 0.15, -0.55]
}
},
"tail3": {
"tail4": {
"rotation": {
"0.0": [37.5, 0, 0],
"0.4167": [0, 0, 0],
@@ -330,20 +299,6 @@
"1.2917": [24.39164, -4.7495, -4.16913]
}
},
"leg_front_left": {
"rotation": {
"0.0": [-27.5, 0, 0],
"0.0417": [32.5, 0, 0],
"0.375": [-18.58597, -7.52076, -21.26765],
"0.5": [-16.10644, -12.0174, -35.79355],
"0.6667": [0.49517, -12.05747, -43.46231],
"1.0": [4.14539, -11.34306, -61.32187],
"1.2083": [4.15, -11.34, -61.32],
"1.25": [-8.52646, 1.41216, 3.24052],
"1.2917": [1.40521, -0.33839, -14.11818],
"1.3333": [11.37038, -0.45956, -9.11953]
}
},
"leg_back_right": {
"rotation": {
"0.0": [-20, 0, 0],
@@ -355,19 +310,6 @@
"1.3333": [35.10477, 0.68983, -3.38568]
}
},
"leg_back_left": {
"rotation": {
"0.0": [-20, 0, 0],
"0.0417": [30, 0, 0],
"0.25": [67.5, 0, 0],
"0.5": [64.96851, 25.25199, -11.26653],
"1.0": [4.96851, 25.25199, -11.26653],
"1.1667": [-10.50411, -2.15804, -13.5601],
"1.2083": [-22.81593, 3.7097, 0.25192],
"1.25": [6.96392, 1.76093, -4.35816],
"1.2917": [-3.03608, 1.76093, -4.35816]
}
},
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
@@ -409,94 +351,6 @@
}
}
}
},
"animation.rattata.cry": {
"animation_length": 0.625,
"bones": {
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [60, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [60, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"tail": {
"rotation": {
"0.0": [0, 0, 0],
"0.125": [15, 0, 0],
"0.2917": [15, 0, 0],
"0.4583": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0417": {
"effect": "pokemon.rattata.cry"
}
}
},
"animation.rattata_male.render": {
"loop": true,
"bones": {
"jaw": {
"rotation": [50, 0, 0]
},
"whisker_right": {
"rotation": [36.07481, 23.1024, 41.77123]
},
"whisker_left": {
"rotation": [0, -7.5, -25]
},
"tail": {
"rotation": [30, 0, 0]
},
"tail2": {
"rotation": [22.5, 0, 0]
},
"tail3": {
"rotation": [25, 0, 0]
},
"leg_front_right": {
"rotation": [-66.88997, 22.29711, 3.09472],
"position": [0, 0, -2.3]
},
"leg_back_left": {
"rotation": [17.35932, 2.24944, -7.15656]
}
}
}
}
}
@@ -3,6 +3,7 @@
"animations": {
"animation.rattata_alolan.ground_idle": {
"loop": true,
"animation_length": 21.375,
"bones": {
"body": {
"rotation": ["math.sin(q.anim_time*90*8)*0.2", 0, 0],
@@ -26,17 +27,25 @@
},
"leg_front_right": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.01,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.02,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"leg_back_right": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.01,-0.025,0.025)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"tail4": {
"rotation": [15, 0, 0]
},
"tail3": {
"rotation": [20, 0, 0]
},
"leg_front_left": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.02,-0.035,0.035)-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
},
"leg_back_left": {
"rotation": ["-math.sin(q.anim_time*90*8)*0.2", 0, 0],
"position": [0, "-math.clamp(math.sin(q.anim_time*90*8+180)*0.05,-0.5,0.5)", 0]
}
}
},
@@ -103,48 +112,257 @@
}
}
},
"animation.rattata_alolan.sleep": {
"loop": true,
"animation.rattata_alolan.mouth_open": {
"animation_length": 1.25,
"bones": {
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [57.5, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.3, -0.5]
}
},
"mouth": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, -0.11],
"0.75": [0, -1, -0.1]
}
}
}
},
"animation.rattata_alolan.standing": {
"animation_length": 2.5,
"bones": {
"body": {
"rotation": [-3.75, 0, 0],
"position": [0, -2.1, 0]
"rotation": {
"0.0": [0, 0, 0],
"0.75": [-82.5, 0, 0],
"1.25": [-82.5, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.4, 0],
"1.125": [0, -0.2, 0],
"1.25": [0, -0.4, 0],
"2.0": [0, 0, 0]
}
},
"head": {
"rotation": ["14.25-math.sin(q.anim_time*90*2)*1", -15.5, 2.5]
},
"whisker_right": {
"rotation": [0, "20.25+math.sin(q.anim_time*90*2-40)*5", 0]
},
"ear_right": {
"rotation": [0, "35.5+math.sin(q.anim_time*90*2-40)*4", 0]
},
"eyelid_right": {
"position": [-0.1, 0, 0]
},
"eyelid_left": {
"position": [0.1, 0, 0]
"rotation": {
"0.0": [0, 0, 0],
"0.75": [85, 0, 0],
"1.25": [85, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, 0.3, -1.7],
"1.25": [0, 0.3, -1.7],
"2.0": [0, 0, 0]
}
},
"tail": {
"rotation": ["-17.5+math.sin(q.anim_time*90*2)*2", "10-math.sin(q.anim_time*90*2-40)*3", -5],
"position": [0, 0, -0.35]
"rotation": {
"0.0": [15, 0, 0],
"0.75": [65, 0, 0],
"1.25": [65, 0, 0],
"2.0": [15, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, 2, -1],
"1.25": [0, 2, -1],
"2.0": [0, 0, 0]
}
},
"tail2": {
"rotation": ["11.25+math.sin(q.anim_time*90*2-40)*2", "28.5-math.sin(q.anim_time*90*2-80)*3", 5.5]
"rotation": {
"0.0": [50, 0, 0],
"0.75": [50, 0, 0],
"1.25": [50, 0, 0],
"2.0": [50, 0, 0]
}
},
"tail3": {
"rotation": {
"0.0": [40, 0, 0],
"0.75": [40, 0, 0],
"1.25": [40, 0, 0],
"2.0": [40, 0, 0]
}
},
"tail4": {
"rotation": ["5-math.sin(q.anim_time*90*2-80)*2", "35.75-math.sin(q.anim_time*90*2-120)*3", 3]
"rotation": {
"0.0": [20, 0, 0],
"0.75": [20, 0, 0],
"1.25": [20, 0, 0],
"2.0": [20, 0, 0]
}
},
"leg_front_right": {
"rotation": [-72.5, 4.25, 10.75],
"position": [0, -0.75, 0]
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 12, 70],
"1.25": [45, 12, 70],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [-0.2, 0.5, 0.5],
"1.25": [-0.2, 0.5, 0.5],
"2.0": [0, 0, 0]
}
},
"leg_front_right_standing": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [0, 0, -35],
"1.25": [0, 0, -35],
"2.0": [0, 0, 0]
}
},
"leg_front_right3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [80, -25, 0],
"1.25": [80, -25, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.3, -0.9, -0.8],
"1.25": [0.3, -0.9, -0.8]
}
},
"leg_front_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, -12, -70],
"1.25": [45, -12, -70],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.2, 0.5, 0.5],
"1.25": [0.2, 0.5, 0.5],
"2.0": [0, 0, 0]
}
},
"leg_front_left_standing": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [0, 0, 35],
"1.25": [0, 0, 35],
"2.0": [0, 0, 0]
}
},
"leg_front_left3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [80, 25, 0],
"1.25": [80, 25, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.3, -0.9, -0.8],
"1.25": [0.3, -0.9, -0.8]
}
},
"leg_back_right": {
"rotation": [83.5, 8.5, -2.5],
"position": [0, -0.5, 0]
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, 27.5],
"1.25": [45, 0, 27.5],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.2, -0.2, 0],
"1.125": [0.2, -0.2, 0.2],
"1.25": [0.2, -0.2, 0],
"2.0": [0, 0, 0]
}
},
"jaw": {
"rotation": ["5+math.sin(q.anim_time*90*2)*4", 0, 0]
"leg_back_right2": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [49.5, 0, 0],
"1.25": [49.5, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.6, -0.7],
"1.25": [0, -0.6, -0.7],
"2.0": [0, 0, 0]
}
},
"leg_back_right3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [-10, 0, -2],
"1.25": [-10, 0, -2],
"2.0": [0, 0, 0]
}
},
"leg_back_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, -27.5],
"1.25": [45, 0, -27.5],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [-0.2, -0.2, 0],
"1.125": [-0.2, -0.2, 0.2],
"1.25": [-0.2, -0.2, 0],
"2.0": [0, 0, 0]
}
},
"leg_back_left2": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [49.5, 0, 0],
"1.25": [49.5, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.6, -0.7],
"1.25": [0, -0.6, -0.7],
"2.0": [0, 0, 0]
}
},
"leg_back_left3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [-10, 0, 2],
"1.25": [-10, 0, 2],
"2.0": [0, 0, 0]
}
},
"leg_front_left4": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, 0],
"1.25": [45, 0, 0],
"2.0": [0, 0, 0]
}
},
"leg_front_right4": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, 0],
"1.25": [45, 0, 0],
"2.0": [0, 0, 0]
}
}
}
},
@@ -312,6 +530,63 @@
}
}
},
"animation.rattata_alolan.sleep": {
"loop": true,
"bones": {
"body": {
"rotation": [-3.75, 0, 0],
"position": [0, -3.1, 0]
},
"head": {
"rotation": ["11.75-math.sin(q.anim_time*90*2)*1", -15.5, 2.5]
},
"whisker_right": {
"rotation": [0, "20.25+math.sin(q.anim_time*90*2-40)*5", 0]
},
"ear_right": {
"rotation": [0, "35.5+math.sin(q.anim_time*90*2-40)*4", 0]
},
"eyelid_right": {
"position": [-0.1, 0, 0]
},
"eyelid_left": {
"position": [0.1, 0, 0]
},
"tail": {
"rotation": ["-17.5+math.sin(q.anim_time*90*2)*2", "10-math.sin(q.anim_time*90*2-40)*3", -5],
"position": [0, 0, -0.35]
},
"tail2": {
"rotation": ["11.25+math.sin(q.anim_time*90*2-40)*2", "28.5-math.sin(q.anim_time*90*2-80)*3", 5.5]
},
"tail4": {
"rotation": ["5-math.sin(q.anim_time*90*2-80)*2", "35.75-math.sin(q.anim_time*90*2-120)*3", 3]
},
"leg_front_right": {
"rotation": [-81.82706, 13.00814, 2.94613],
"position": [0, -0.75, 0]
},
"leg_back_right": {
"rotation": [65.81451, -6.32173, 19.33562],
"position": [0, -0.5, 0]
},
"jaw": {
"rotation": ["5+math.sin(q.anim_time*90*2)*4", 0, 0]
},
"leg_front_left": {
"rotation": [-65.929, -37.44427, -4.88648]
},
"leg_back_right2": {
"rotation": [5, 0, 0]
},
"leg_back_left": {
"rotation": [58.31451, 6.32173, -19.33562]
},
"leg_back_left2": {
"rotation": [5, 0, 0]
}
}
},
"animation.rattata_alolan.blink": {
"animation_length": 0.16667,
"bones": {
@@ -331,253 +606,21 @@
}
}
},
"animation.rattata_alolan.mouth_open": {
"animation_length": 1.25,
"animation.rattata_alolan.blink2": {
"animation_length": 0.16667,
"bones": {
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [57.5, 0, 0]
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.3, -0.5]
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": [0, 0, 0]
}
},
"mouth": {
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, -0.11],
"0.75": [0, -1, -0.1]
}
}
}
},
"animation.rattata_alolan.standing": {
"animation_length": 2.5,
"bones": {
"body": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [-82.5, 0, 0],
"1.25": [-82.5, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.4, 0],
"1.25": [0, -0.4, 0],
"2.0": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [85, 0, 0],
"1.25": [85, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, 0.3, -1.7],
"1.25": [0, 0.3, -1.7],
"2.0": [0, 0, 0]
}
},
"tail": {
"rotation": {
"0.0": [15, 0, 0],
"0.75": [65, 0, 0],
"1.25": [65, 0, 0],
"2.0": [15, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, 2, -1],
"1.25": [0, 2, -1],
"2.0": [0, 0, 0]
}
},
"tail2": {
"rotation": {
"0.0": [50, 0, 0],
"0.75": [50, 0, 0],
"1.25": [50, 0, 0],
"2.0": [50, 0, 0]
}
},
"tail3": {
"rotation": {
"0.0": [40, 0, 0],
"0.75": [40, 0, 0],
"1.25": [40, 0, 0],
"2.0": [40, 0, 0]
}
},
"tail4": {
"rotation": {
"0.0": [20, 0, 0],
"0.75": [20, 0, 0],
"1.25": [20, 0, 0],
"2.0": [20, 0, 0]
}
},
"leg_front_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 12, 70],
"1.25": [45, 12, 70],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [-0.2, 0.5, 0.5],
"1.25": [-0.2, 0.5, 0.5],
"2.0": [0, 0, 0]
}
},
"leg_front_right_standing": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [0, 0, -35],
"1.25": [0, 0, -35],
"2.0": [0, 0, 0]
}
},
"leg_front_right3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [80, -25, 0],
"1.25": [80, -25, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.3, -0.9, -0.8],
"1.25": [0.3, -0.9, -0.8]
}
},
"leg_front_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, -12, -70],
"1.25": [45, -12, -70],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.2, 0.5, 0.5],
"1.25": [0.2, 0.5, 0.5],
"2.0": [0, 0, 0]
}
},
"leg_front_left_standing": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [0, 0, 35],
"1.25": [0, 0, 35],
"2.0": [0, 0, 0]
}
},
"leg_front_left3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [80, 25, 0],
"1.25": [80, 25, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.3, -0.9, -0.8],
"1.25": [0.3, -0.9, -0.8]
}
},
"leg_back_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, 27.5],
"1.25": [45, 0, 27.5],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0.2, -0.2, 0],
"1.25": [0.2, -0.2, 0],
"2.0": [0, 0, 0]
}
},
"leg_back_right2": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [49.5, 0, 0],
"1.25": [49.5, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.6, -0.7],
"1.25": [0, -0.6, -0.7],
"2.0": [0, 0, 0]
}
},
"leg_back_right3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [-10, 0, -2],
"1.25": [-10, 0, -2],
"2.0": [0, 0, 0]
}
},
"leg_back_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, -27.5],
"1.25": [45, 0, -27.5],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [-0.2, -0.2, 0],
"1.25": [-0.2, -0.2, 0],
"2.0": [0, 0, 0]
}
},
"leg_back_left2": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [49.5, 0, 0],
"1.25": [49.5, 0, 0],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.75": [0, -0.6, -0.7],
"1.25": [0, -0.6, -0.7],
"2.0": [0, 0, 0]
}
},
"leg_back_left3": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [-10, 0, 2],
"1.25": [-10, 0, 2],
"2.0": [0, 0, 0]
}
},
"leg_front_left4": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, 0],
"1.25": [45, 0, 0],
"2.0": [0, 0, 0]
}
},
"leg_front_right4": {
"rotation": {
"0.0": [0, 0, 0],
"0.75": [45, 0, 0],
"1.25": [45, 0, 0],
"2.0": [0, 0, 0]
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": [0, 0, 0]
}
}
}
@@ -696,6 +696,86 @@
}
}
}
},
"animation.raticate.cry": {
"animation_length": 0.79167,
"bones": {
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [-9.06, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"snout": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [-7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [-7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5417": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [20, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": [12.5, 0, 0],
"0.1667": [15, 0, 0],
"0.2083": [12.5, 0, 0],
"0.25": [15, 0, 0],
"0.2917": [12.5, 0, 0],
"0.5417": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.0833": {
"effect": "pokemon.raticate.cry"
}
}
}
}
}
@@ -3,63 +3,347 @@
"animations": {
"animation.zubat.ground_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": ["36-25*(math.sin(q.anim_time*90*8*1)*0.2+1)", 0, 0],
"position": [
"math.clamp(math.sin(q.anim_time*90*4)*0.5,-0.1,0)+math.clamp(math.sin(q.anim_time*90*4)*0.5,0,0.1)+math.sin(q.anim_time*90*4)*0.5",
"math.clamp(math.sin(q.anim_time*90*2)*1.2,-1,0)+math.clamp(math.sin(q.anim_time*90*2)*1.2,0,1)+math.sin(q.anim_time*90*2)*1",
"math.sin(q.anim_time*90*2)*1"
]
"rotation": ["45+math.cos(q.anim_time*90*16-90)*4", 0, "math.cos(q.anim_time*90*3-30)*4"],
"position": ["math.cos(q.anim_time*90*3-100)*2", "4+math.cos(q.anim_time*90*16)*0.5+math.cos(q.anim_time*90*2-100)*2", -1]
},
"mouth_closed": {
"rotation": [0, 0, 0]
"torso": {
"rotation": [-15, 0, 0]
},
"rightear": {
"rotation": ["36-40*(math.sin(q.anim_time*90*8*1)*0.2+1)", 0, 0]
"wing_left": {
"rotation": [2.8828, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"leftear": {
"rotation": ["36-40*(math.sin(q.anim_time*90*8*1)*0.2+1)", 0, 0]
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"rightwing": {
"rotation": [0, "45-25*(math.sin(q.anim_time*90*8*3)*1.5+1)", 0]
"leg_left": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, -7.5]
},
"leftwing": {
"rotation": [0, "-45+25*(math.sin(q.anim_time*90*8*3)*1.5+1)", 0]
"leg_left2": {
"rotation": ["12.3964+math.cos(q.anim_time*90*16-240)*7", 1.61888, -7.32417]
},
"legs": {
"rotation": ["36-40*(math.sin(q.anim_time*80*8*1)*0.2+1)", 0, 0]
"leg_left3": {
"rotation": ["15+math.cos(q.anim_time*90*16-280)*8", 0, 0]
},
"leg_right": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, 7.5]
},
"leg_right2": {
"rotation": ["12.3964+math.cos(q.anim_time*90*16-240)*7", -1.61888, 7.32417]
},
"leg_right3": {
"rotation": ["15+math.cos(q.anim_time*90*16-280)*8", 0, 0]
},
"wing_right": {
"rotation": [2.8828, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"ear_left": {
"rotation": [0, "math.cos(q.anim_time*90*16-200)*8", 0]
},
"ear_right": {
"rotation": [0, "-math.cos(q.anim_time*90*16-200)*8", 0]
},
"wing_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
},
"wing_folded_right": {
"rotation": [2.8828, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_folded_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"wing_folded_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_folded_left": {
"rotation": [2.8828, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"wing_folded_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"wing_folded_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
}
}
},
"animation.zubat.ground_walk": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": ["75-25*(math.sin(q.anim_time*90*8*1)*0.2+1)", 0, 0],
"position": [
"math.clamp(math.sin(q.anim_time*90*2)*0.5,-0.1,0)+math.clamp(math.sin(q.anim_time*90*2)*0.5,0,0.1)+math.sin(q.anim_time*90*3)*0.5",
"math.clamp(math.sin(q.anim_time*90*2)*1.2,-1,0)+math.clamp(math.sin(q.anim_time*90*2)*1.2,0,1)+math.sin(q.anim_time*90*3)*1",
"math.sin(q.anim_time*90*3)*1"
]
"rotation": ["65+math.cos(q.anim_time*90*16-90)*6", 0, "math.cos(q.anim_time*90*6-30)*4"],
"position": ["math.cos(q.anim_time*90*6-100)*1", "4+math.cos(q.anim_time*90*16)*0.25+math.cos(q.anim_time*90*4-100)*1", -2]
},
"mouth_closed": {
"rotation": [0, 0, 0]
"torso": {
"rotation": [-15, 0, 0]
},
"rightear": {
"rotation": ["30-40*(math.sin(q.anim_time*90*8*1)*0.2+1)", 0, 0]
"wing_left": {
"rotation": [2.88284, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"leftear": {
"rotation": ["30-40*(math.sin(q.anim_time*90*8*1)*0.2+1)", 0, 0]
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"rightwing": {
"rotation": [0, "45-25*(math.sin(q.anim_time*90*8*3)*1.5+1)", 0]
"leg_left": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, -7.5]
},
"leftwing": {
"rotation": [0, "-45+25*(math.sin(q.anim_time*90*8*3)*1.5+1)", 0]
"leg_left2": {
"rotation": ["5+math.cos(q.anim_time*90*16-240)*9", 1.61888, -7.32417]
},
"leg_left3": {
"rotation": ["5+math.cos(q.anim_time*90*16-280)*12", 0, 0]
},
"leg_right": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, 7.5]
},
"leg_right2": {
"rotation": ["5+math.cos(q.anim_time*90*16-240)*8", -1.61888, 7.32417]
},
"leg_right3": {
"rotation": ["5+math.cos(q.anim_time*90*16-280)*12", 0, 0]
},
"wing_right": {
"rotation": [2.88284, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"ear_left": {
"rotation": [0, "-25+math.cos(q.anim_time*90*16-200)*12", 0]
},
"ear_right": {
"rotation": [0, "25-math.cos(q.anim_time*90*16-200)*12", 0]
},
"legs": {
"rotation": ["36-40*(math.sin(q.anim_time*80*8*1)*0.2+1)", 0, 0]
"rotation": [15, 0, 0]
},
"wing_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
},
"wing_folded_right": {
"rotation": [2.8828, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_folded_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"wing_folded_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_folded_left": {
"rotation": [2.8828, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"wing_folded_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"wing_folded_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
}
}
},
"animation.zubat.air_idle": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": ["45+math.cos(q.anim_time*90*16-90)*4", 0, "math.cos(q.anim_time*90*3-30)*4"],
"position": ["math.cos(q.anim_time*90*3-100)*2", "4+math.cos(q.anim_time*90*16)*0.5+math.cos(q.anim_time*90*2-100)*2", -1]
},
"torso": {
"rotation": [-15, 0, 0]
},
"wing_left": {
"rotation": [2.8828, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"leg_left": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, -7.5]
},
"leg_left2": {
"rotation": ["12.3964+math.cos(q.anim_time*90*16-240)*7", 1.61888, -7.32417]
},
"leg_left3": {
"rotation": ["15+math.cos(q.anim_time*90*16-280)*8", 0, 0]
},
"leg_right": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, 7.5]
},
"leg_right2": {
"rotation": ["12.3964+math.cos(q.anim_time*90*16-240)*7", -1.61888, 7.32417]
},
"leg_right3": {
"rotation": ["15+math.cos(q.anim_time*90*16-280)*8", 0, 0]
},
"wing_right": {
"rotation": [2.8828, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"ear_left": {
"rotation": [0, "math.cos(q.anim_time*90*16-200)*8", 0]
},
"ear_right": {
"rotation": [0, "-math.cos(q.anim_time*90*16-200)*8", 0]
},
"wing_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
},
"wing_folded_right": {
"rotation": [2.8828, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_folded_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"wing_folded_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_folded_left": {
"rotation": [2.8828, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"wing_folded_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"wing_folded_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
}
}
},
"animation.zubat.air_fly": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": ["65+math.cos(q.anim_time*90*16-90)*6", 0, "math.cos(q.anim_time*90*6-30)*4"],
"position": ["math.cos(q.anim_time*90*6-100)*1", "4+math.cos(q.anim_time*90*16)*0.25+math.cos(q.anim_time*90*4-100)*1", -2]
},
"torso": {
"rotation": [-15, 0, 0]
},
"wing_left": {
"rotation": [2.88284, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"leg_left": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, -7.5]
},
"leg_left2": {
"rotation": ["5+math.cos(q.anim_time*90*16-240)*9", 1.61888, -7.32417]
},
"leg_left3": {
"rotation": ["5+math.cos(q.anim_time*90*16-280)*12", 0, 0]
},
"leg_right": {
"rotation": ["math.cos(q.anim_time*90*16-190)*6", 0, 7.5]
},
"leg_right2": {
"rotation": ["5+math.cos(q.anim_time*90*16-240)*8", -1.61888, 7.32417]
},
"leg_right3": {
"rotation": ["5+math.cos(q.anim_time*90*16-280)*12", 0, 0]
},
"wing_right": {
"rotation": [2.88284, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"ear_left": {
"rotation": [0, "-25+math.cos(q.anim_time*90*16-200)*12", 0]
},
"ear_right": {
"rotation": [0, "25-math.cos(q.anim_time*90*16-200)*12", 0]
},
"legs": {
"rotation": [15, 0, 0]
},
"wing_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
},
"wing_folded_right": {
"rotation": [2.8828, "10-math.cos(q.anim_time*90*16-300)*50", 7.1392]
},
"wing_folded_right2": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-25)*24)", 0]
},
"wing_folded_right3": {
"rotation": [0, "-15-math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_right4": {
"rotation": [0, "-(math.cos(q.anim_time*90*16-75)*24)", 0]
},
"wing_folded_left": {
"rotation": [2.8828, "-10+math.cos(q.anim_time*90*16-300)*50", -7.1392]
},
"wing_folded_left2": {
"rotation": [0, "math.cos(q.anim_time*90*16-25)*24", 0]
},
"wing_folded_left3": {
"rotation": [0, "15+math.cos(q.anim_time*90*16-50)*48", 0]
},
"wing_folded_left4": {
"rotation": [0, "math.cos(q.anim_time*90*16-75)*24", 0]
}
}
},
@@ -67,23 +351,478 @@
"loop": true,
"bones": {
"body": {
"rotation": [90, 0, 0],
"position": [0, -5.5, 5]
"rotation": [85, 0, 0],
"position": [0, -10, -5]
},
"legs": {
"rotation": [-12.5, 0, 0]
"ear_left": {
"rotation": [0, 32.5, 0]
},
"rightear": {
"rotation": [20, 0, 0]
"ear_right": {
"rotation": [0, -32.5, 0]
},
"leftear": {
"rotation": [20, 0, 0]
"wing_left": {
"rotation": [2.5, 15, 0]
},
"rightwing": {
"wing_left2": {
"rotation": [0, -7.5, 0]
},
"leftwing": {
"wing_right": {
"rotation": [2.5, -15, 0]
},
"wing_right2": {
"rotation": [0, 7.5, 0]
},
"leg_left": {
"rotation": [-22.2982, -0.55025, -7.88438]
},
"leg_left2": {
"rotation": [17.5, 0, 0]
},
"leg_left3": {
"rotation": [7.5, 0, 0]
},
"leg_right": {
"rotation": [-22.1423, -0.82062, 11.13915]
},
"leg_right2": {
"rotation": [17.5, 0, 0]
},
"leg_right3": {
"rotation": [7.5, 0, 0]
},
"wing_right3": {
"rotation": [0, 5, 0]
},
"wing_right4": {
"rotation": [0, 2.5, 0]
},
"wing_left3": {
"rotation": [0, -5, 0]
},
"wing_left4": {
"rotation": [0, -2.5, 0]
}
}
},
"animation.zubat.eartwitch": {
"animation_length": 0.5,
"bones": {
"ear_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": [0, 10, 0],
"0.125": [0, "-(math.cos(q.anim_time*90*32)*16)", 0],
"0.2917": [0, 0, 0]
}
},
"ear_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": [0, -10, 0],
"0.125": [0, "math.cos(q.anim_time*90*32)*16", 0],
"0.2917": [0, 0, 0]
}
}
}
},
"animation.zubat.roost": {
"loop": true,
"animation_length": 2.54167,
"bones": {
"body": {
"rotation": ["175+math.cos(q.anim_time*90*1.5)*1", 180, 0],
"position": [0, 0, "0-math.cos(q.anim_time*90*1.5)*0.3"]
},
"ear_left": {
"rotation": [0, 12.5, -27.5],
"position": [-1, 0, 0]
},
"ear_right": {
"rotation": [0, -12.5, 27.5],
"position": [1, 0, 0]
},
"wing_left": {
"rotation": [3.05656, 42.60004, -5.08658],
"scale": [0.5, 1, 1]
},
"wing_left2": {
"rotation": [0, 135, 0]
},
"wing_right": {
"rotation": [12.66289, -50.29336, -2.03936],
"position": [0, 0, 0],
"scale": [0.5, 1, 1]
},
"wing_right2": {
"rotation": [0, -117.5, 0]
},
"leg_left": {
"rotation": [5, 0, -2.5]
},
"leg_left2": {
"rotation": [0, 0, 0]
},
"leg_left3": {
"rotation": [0, 0, 0]
},
"leg_right": {
"rotation": [5, 0, 2.5]
},
"leg_right2": {
"rotation": [0, 0, 0]
},
"leg_right3": {
"rotation": [0, 0, 0]
},
"mouth_open": {
"position": [0, 0, 1]
},
"mouth_closed": {
"position": [0, 0, -1]
},
"teeth_closed_top_right": {
"scale": 1
},
"wing_folded_right": {
"rotation": [5.67501, -47.70051, -2.66124],
"position": [0, 0, -1],
"scale": [0.6, 1, 0.75]
},
"wing_folded_right2": {
"rotation": [0, -77.5, 0]
},
"wing_folded_right3": {
"rotation": [0, -70, 0]
},
"wing_folded_right4": {
"rotation": [0, -25, 0]
},
"wing_folded_left": {
"rotation": [15.9664, 69.40933, 14.34857],
"position": [0, 0, -1],
"scale": [0.3, 1, 1]
},
"wing_folded_left2": {
"rotation": [0, 20, 0]
},
"wing_folded_left3": {
"rotation": [0, 110, 0]
},
"wing_folded_left4": {
"rotation": [0, 32.5, 0]
}
}
},
"animation.zubat.mouth_wide": {
"loop": true,
"bones": {
"mouth_open_bottom": {
"position": [0, -1, 0]
}
}
},
"animation.zubat.cry": {
"animation_length": 1,
"bones": {
"torso": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [-1.7, 0, 0],
"post": [-1.7, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [-2.4, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [-1.7, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [-0.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [0.6, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": [0, 0, 0]
}
},
"mouth_open_bottom": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.5, 0],
"0.3333": [0, -0.5, 0],
"0.375": [0, 0, 0],
"0.4167": [0, -0.6, 0],
"0.5417": [0, -0.6, 0],
"0.5833": [0, -0.3, 0],
"0.6667": [0, -0.3, 0],
"0.7083": [0, 0, 0]
}
},
"wings_open": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [1.7, 0, 0],
"post": [1.7, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [2.4, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [1.7, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [-0.6, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": [0, 0, 0]
}
},
"wings_folded": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [1.7, 0, 0],
"post": [1.7, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [2.4, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [1.7, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [-0.6, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": [0, 0, 0]
}
},
"body": {
"rotation": {
"0.0": [0, 0, 0],
"0.1667": ["math.cos(q.anim_time*90*400)*7", 0, 0],
"0.3333": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "zubat"
}
}
},
"animation.zubat.shoulder_left": {
"loop": true,
"animation_length": 2.54167,
"bones": {
"body": {
"rotation": ["-5+math.cos(q.anim_time*90*1.5)*0.2", 0, 0],
"position": [1, -7.8, 0]
},
"ear_left": {
"rotation": [0, -2.5, -27.5],
"position": [-1, 0, 0]
},
"ear_right": {
"rotation": [0, -2.5, 27.5],
"position": [1, 0, 0]
},
"wing_left": {
"rotation": [3.05656, 42.60004, -5.08658],
"scale": [0.5, 1, 1]
},
"wing_left2": {
"rotation": [0, 135, 0]
},
"wing_right": {
"rotation": [12.66289, -50.29336, -2.03936],
"position": [0, 0, 0],
"scale": [0.5, 1, 1]
},
"wing_right2": {
"rotation": [0, -117.5, 0]
},
"leg_left": {
"rotation": [47.5, 0, -2.5]
},
"leg_left2": {
"rotation": [-30, 0, 0]
},
"leg_left3": {
"rotation": [-10, 0, 0]
},
"leg_right": {
"rotation": [47.5, 0, 2.5]
},
"leg_right2": {
"rotation": [-30, 0, 0]
},
"leg_right3": {
"rotation": [-10, 0, 0]
},
"mouth_open": {
"position": [0, 0, 1]
},
"mouth_closed": {
"position": [0, 0, -1]
},
"teeth_closed_top_right": {
"scale": 1
},
"wing_folded_right": {
"rotation": [6.30117, -52.67334, -3.47564],
"position": [0, 0, -1],
"scale": [0.6, 1, 0.75]
},
"wing_folded_right2": {
"rotation": [0, -67.5, 0]
},
"wing_folded_right3": {
"rotation": [0, -70, 0]
},
"wing_folded_right4": {
"rotation": [0, -25, 0]
},
"wing_folded_left": {
"rotation": [9.65097, 54.75649, 7.2616],
"position": [0, 0, -1],
"scale": [0.3, 1, 1]
},
"wing_folded_left2": {
"rotation": [0, 20, 0]
},
"wing_folded_left3": {
"rotation": [0, 110, 0]
},
"wing_folded_left4": {
"rotation": [0, 37.5, 0]
},
"torso": {
"rotation": [0, 0, 0]
}
}
},
"animation.zubat.shoulder_right": {
"loop": true,
"animation_length": 2.54167,
"bones": {
"body": {
"rotation": ["-5+math.cos(q.anim_time*90*1.5)*0.2", 0, 0],
"position": [-1, -7.8, 0]
},
"ear_left": {
"rotation": [0, -2.5, -27.5],
"position": [-1, 0, 0]
},
"ear_right": {
"rotation": [0, -2.5, 27.5],
"position": [1, 0, 0]
},
"wing_left": {
"rotation": [3.05656, 42.60004, -5.08658],
"scale": [0.5, 1, 1]
},
"wing_left2": {
"rotation": [0, 135, 0]
},
"wing_right": {
"rotation": [12.66289, -50.29336, -2.03936],
"position": [0, 0, 0],
"scale": [0.5, 1, 1]
},
"wing_right2": {
"rotation": [0, -117.5, 0]
},
"leg_left": {
"rotation": [47.5, 0, -2.5]
},
"leg_left2": {
"rotation": [-30, 0, 0]
},
"leg_left3": {
"rotation": [-10, 0, 0]
},
"leg_right": {
"rotation": [47.5, 0, 2.5]
},
"leg_right2": {
"rotation": [-30, 0, 0]
},
"leg_right3": {
"rotation": [-10, 0, 0]
},
"mouth_open": {
"position": [0, 0, 1]
},
"mouth_closed": {
"position": [0, 0, -1]
},
"teeth_closed_top_right": {
"scale": 1
},
"wing_folded_right": {
"rotation": [6.30117, -52.67334, -3.47564],
"position": [0, 0, -1],
"scale": [0.6, 1, 0.75]
},
"wing_folded_right2": {
"rotation": [0, -67.5, 0]
},
"wing_folded_right3": {
"rotation": [0, -70, 0]
},
"wing_folded_right4": {
"rotation": [0, -25, 0]
},
"wing_folded_left": {
"rotation": [9.65097, 54.75649, 7.2616],
"position": [0, 0, -1],
"scale": [0.3, 1, 1]
},
"wing_folded_left2": {
"rotation": [0, 20, 0]
},
"wing_folded_left3": {
"rotation": [0, 110, 0]
},
"wing_folded_left4": {
"rotation": [0, 37.5, 0]
},
"torso": {
"rotation": [0, 0, 0]
}
}
}
@@ -1,24 +1,899 @@
{
"format_version": "1.8.0",
"animations": {
"animation.golbat.ground_idle": {
"loop": true,
"animation_length": 2,
"bones": {
"wing_left_rotation": {
"rotation": [0, "15+math.cos(q.anim_time*90*2-60)*3", 0]
},
"wing_left2": {
"rotation": [0, "15+math.cos(q.anim_time*90*2-120)*4", 0]
},
"legs": {
"rotation": [-17.5, 0, 0]
},
"leg_left": {
"rotation": [22.5, "5+math.cos(q.anim_time*90*2)*2", "20-math.cos(q.anim_time*90*2)*4"]
},
"leg_left2": {
"rotation": [0, 10, "-5+math.cos(q.anim_time*90*2)*4.1"]
},
"toes_left": {
"rotation": [0, 0, -2.5]
},
"toes_inner_left": {
"rotation": [0, 0, -15]
},
"leg_right": {
"rotation": [22.5, "-5-math.cos(q.anim_time*90*2)*2", "-20+math.cos(q.anim_time*90*2)*4"]
},
"leg_right2": {
"rotation": [0, -10, "5-math.cos(q.anim_time*90*2)*4.1"]
},
"toes_right": {
"rotation": [0, 0, 2.5]
},
"toes_inner_right": {
"rotation": [0, 0, 15]
},
"body": {
"rotation": [10, 0, 0],
"position": [0, "1.1-math.cos(q.anim_time*90*2)*0.26", "math.cos(q.anim_time*90*2)*0.05"]
},
"wing_left": {
"rotation": [5.22206, "-14.6575+math.cos(q.anim_time*90*2-30)*4", -9.13039]
},
"wing_right": {
"rotation": [5.22206, "14.6575-math.cos(q.anim_time*90*2-30)*4", 9.13039]
},
"wing_right_rotation": {
"rotation": [0, "-15-math.cos(q.anim_time*90*2-60)*3", 0]
},
"wing_right2": {
"rotation": [0, "-15-math.cos(q.anim_time*90*2-120)*4", 0]
},
"tongue": {
"rotation": [-90, 0, 0],
"position": [0, -1, 3]
},
"tongue2": {
"rotation": [-180, 0, 0],
"scale": [1, 1, 0.3]
},
"torso": {
"rotation": ["-5+math.cos(q.anim_time*90*2)*2", 0, 0]
},
"pupil_left": {
"scale": 1
},
"mouth_closed": {
"position": [0, 0, 0]
},
"toes_outer_left": {
"rotation": [0, 0, -10]
},
"toes_outer_right": {
"rotation": [0, 0, 10]
},
"wing_left3": {
"rotation": [0, "10+math.cos(q.anim_time*90*2-160)*4", 0]
},
"wing_left4": {
"rotation": [0, "10+math.cos(q.anim_time*90*2-200)*4", 0]
},
"wing_right3": {
"rotation": [0, "-10-math.cos(q.anim_time*90*2-160)*4", 0]
},
"wing_right4": {
"rotation": [0, "-10-math.cos(q.anim_time*90*2-200)*4", 0]
}
}
},
"animation.golbat.ground_walk": {
"loop": true,
"animation_length": 3,
"bones": {
"wing_left_rotation": {
"rotation": [0, "30+math.sin(q.anim_time*90*4-45)*12", "-5+math.sin(q.anim_time*90*4-80)*8"],
"position": ["-1+(math.sin(q.anim_time*90*4-80)*0.2)", 0, "-(math.sin(q.anim_time*90*4-80)*0.4)"]
},
"wing_left2": {
"rotation": [0, "10+math.sin(q.anim_time*90*4-55)*18", 0]
},
"legs": {
"rotation": [-17.5, 0, 0]
},
"leg_left": {
"rotation": [22.5, "5+math.clamp(math.cos(q.anim_time*90*4+90)*40,0,90)", "20-math.clamp(math.cos(q.anim_time*90*4+135)*32,0,90)"]
},
"leg_left2": {
"rotation": {
"0.0": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"0.4583": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"0.5833": [-7.40702, 6.73717, "-31.9364+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"0.7917": [-7.40702, 6.73717, "-44.9364+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"1.0": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"1.4583": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"1.5833": [-7.40702, 6.73717, "-31.9364+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"1.7917": [-7.40702, 6.73717, "-44.9364+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"2.0": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"2.4583": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"2.5833": [-7.40702, 6.73717, "-31.9364+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"2.7917": [-7.40702, 6.73717, "-44.9364+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"],
"3.0": [0, 10, "-5+math.clamp(math.cos(q.anim_time*90*4+135)*6,0,90)+math.clamp(math.cos(q.anim_time*90*4+90)*6,-20,0)"]
}
},
"toes_left": {
"rotation": {
"0.0": [-20, 0, -2.5],
"0.3333": [0, 0, -2.5],
"0.6667": [-9.42313, 3.41027, 17.21885],
"1.0": [-20, 0, -2.5],
"1.3333": [0, 0, -2.5],
"1.6667": [-9.42313, 3.41027, 17.21885],
"2.0": [-20, 0, -2.5],
"2.3333": [0, 0, -2.5],
"2.6667": [-9.42313, 3.41027, 17.21885],
"3.0": [-20, 0, -2.5]
}
},
"toes_inner_left": {
"rotation": [0, 0, -15]
},
"leg_right": {
"rotation": [22.5, "-5+math.clamp(math.cos(q.anim_time*90*4+90)*40,-90,0)", "-20-math.clamp(math.cos(q.anim_time*90*4+135)*32,-90,0)"]
},
"leg_right2": {
"rotation": {
"0.0": [-1.93, -9.39, 7.56],
"0.0833": [-5.77509, -8.17773, "25.413+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"0.3333": [-7.69263, -6.40865, "45.4311+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"0.5": [0, -10, "5+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"0.9583": [0, -10, "5+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"1.0": [-1.93, -9.39, 7.56],
"1.0833": [-5.77509, -8.17773, "25.413+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"1.3333": [-7.69263, -6.40865, "45.4311+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"1.5": [0, -10, "5+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"1.9583": [0, -10, "5+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"2.0": [-1.93, -9.39, 7.56],
"2.0833": [-5.77509, -8.17773, "25.413+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"2.3333": [-7.69263, -6.40865, "45.4311+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"2.5": [0, -10, "5+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"2.9583": [0, -10, "5+math.clamp(math.cos(q.anim_time*90*4+135)*6,-90,0)+math.clamp(math.cos(q.anim_time*90*4+90)*6,0,20)"],
"3.0": [-1.93, -9.39, 7.56]
}
},
"toes_right": {
"rotation": {
"0.0": [-4.71, -1.71, -7.36],
"0.1667": [-9.42313, -3.41027, -17.21885],
"0.5": [-20, 0, 2.5],
"0.8333": [0, 0, 2.5],
"1.1667": [-9.42313, -3.41027, -17.21885],
"1.5": [-20, 0, 2.5],
"1.8333": [0, 0, 2.5],
"2.1667": [-9.42313, -3.41027, -17.21885],
"2.5": [-20, 0, 2.5],
"2.8333": [0, 0, 2.5],
"3.0": [-4.71, -1.71, -7.36]
}
},
"toes_inner_right": {
"rotation": [0, 0, 15]
},
"body": {
"rotation": [10, "math.cos(q.anim_time*90*4)*16", "math.cos(q.anim_time*90*4-90)*8"],
"position": [0, "1+math.abs(math.sin(q.anim_time*90*4-5)*1.4)", 0]
},
"wing_left": {
"rotation": [5.22206, "-34.6575+math.sin(q.anim_time*90*4)*8", -9.13039]
},
"wing_right": {
"rotation": [5.22206, "34.6575+math.sin(q.anim_time*90*4)*8", 9.13039]
},
"wing_right_rotation": {
"rotation": [0, "-30+math.sin(q.anim_time*90*4-45)*12", "5+(math.sin(q.anim_time*90*4-80)*8)"],
"position": ["1+(math.sin(q.anim_time*90*4-80)*0.2)", 0, "(math.sin(q.anim_time*90*4-80)*0.2)"]
},
"wing_right2": {
"rotation": [0, "-10+math.sin(q.anim_time*90*4-55)*18", 0]
},
"tongue": {
"rotation": [-90, 0, 0],
"position": [0, -1, 3]
},
"tongue2": {
"rotation": [-180, 0, 0],
"scale": [1, 1, 0.3]
},
"torso": {
"rotation": ["-5+math.sin(q.anim_time*90*8-45)*4", 0, 0]
},
"pupil_left": {
"scale": 1
},
"mouth_closed": {
"position": [0, 0, 0]
},
"toes_outer_left": {
"rotation": {
"0.0": [0, 0, -10],
"0.375": [0, 0, -10],
"0.9167": [0, 0, 22.5],
"1.0": [0, 0, -10],
"1.375": [0, 0, -10],
"1.9167": [0, 0, 22.5],
"2.0": [0, 0, -10],
"2.375": [0, 0, -10],
"2.9167": [0, 0, 22.5],
"3.0": [0, 0, -10]
}
},
"toes_outer_right": {
"rotation": {
"0.0": [0, 0, 2.5],
"0.4167": [0, 0, -22.5],
"0.5": [0, 0, 10],
"0.875": [0, 0, 10],
"1.4167": [0, 0, -22.5],
"1.5": [0, 0, 10],
"1.875": [0, 0, 10],
"2.4167": [0, 0, -22.5],
"2.5": [0, 0, 10],
"2.875": [0, 0, 10],
"3.0": [0, 0, 2.5]
}
},
"wing_left3": {
"rotation": [0, "math.sin(q.anim_time*90*4-85)*18", 0]
},
"wing_left4": {
"rotation": [0, "math.sin(q.anim_time*90*4-110)*6", 0]
},
"wing_right3": {
"rotation": [0, "math.sin(q.anim_time*90*4-85)*18", 0]
},
"wing_right4": {
"rotation": [0, "math.sin(q.anim_time*90*4-110)*6", 0]
}
}
},
"animation.golbat.air_idle": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"body": {
"rotation": ["20+math.cos(q.anim_time*90*12-135)*2", 0, "math.cos(q.anim_time*90*3)*2"],
"position": ["math.cos(q.anim_time*90*3-45)*0.8", "7+math.cos(q.anim_time*90*12)*0.5+math.cos(q.anim_time*90*6)*1", "math.cos(q.anim_time*90*12)*0.25"]
},
"tongue": {
"rotation": [-90, 0, 0],
"position": [0, -1, 3]
},
"tongue2": {
"rotation": [-180, 0, 0],
"scale": [1, 1, 0.3]
},
"wing_left_rotation": {
"rotation": ["20-math.cos(q.anim_time*90*12-25)*24", "math.cos(q.anim_time*90*12-300)*55", 0],
"position": ["-1+math.cos(q.anim_time*90*12-180)*0.5", 0, 0]
},
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*12-40)*32", 0]
},
"wing_right_rotation": {
"rotation": ["20-math.cos(q.anim_time*90*12-25)*24", "-(math.cos(q.anim_time*90*12-300)*55)", 0],
"position": ["1-math.cos(q.anim_time*90*12-180)*0.5", 0, 0]
},
"wing_right2": {
"rotation": [0, "-math.cos(q.anim_time*90*12-40)*32", 0]
},
"leg_left": {
"rotation": [55.18392, "14.9084-math.cos(q.anim_time*90*3+45)*12", "42.8018+math.cos(q.anim_time*90*3+45)*12"]
},
"leg_left2": {
"rotation": [0, 0, "-30-math.cos(q.anim_time*90*3+45)*6"]
},
"leg_right": {
"rotation": [55.18392, "-14.9084-math.cos(q.anim_time*90*3+45)*12", "-42.8018+math.cos(q.anim_time*90*3+45)*12"]
},
"leg_right2": {
"rotation": [0, 0, "30-math.cos(q.anim_time*90*3+45)*6"]
},
"wings": {
"rotation": [15, 0, 0]
},
"wing_left": {
"rotation": ["0-math.cos(q.anim_time*90*12-40)*8", "math.cos(q.anim_time*90*12+40)*42", 0]
},
"wing_left3": {
"rotation": [0, "math.cos(q.anim_time*90*12-90)*32", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*12-120)*18", 0]
},
"wing_right": {
"rotation": ["0-math.cos(q.anim_time*90*12-40)*8", "-math.cos(q.anim_time*90*12+40)*42", 0]
},
"wing_right3": {
"rotation": [0, "-math.cos(q.anim_time*90*12-90)*32", 0]
},
"wing_right4": {
"rotation": [0, "-math.cos(q.anim_time*90*12-120)*18", 0]
}
}
},
"animation.golbat.air_fly": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"body": {
"rotation": ["50+math.cos(q.anim_time*90*12-90)*3", 0, 0],
"position": ["math.cos(q.anim_time*90*6)*0.5", "10+math.cos(q.anim_time*90*12)*0.5", "2-math.cos(q.anim_time*90*12)*1"]
},
"tongue": {
"rotation": [-90, 0, 0],
"position": [0, -1, 3]
},
"tongue2": {
"rotation": [-180, 0, 0],
"scale": [1, 1, 0.3]
},
"wing_left_rotation": {
"rotation": ["10-math.cos(q.anim_time*90*12-25)*12", "-10+math.cos(q.anim_time*90*12-300)*55", 0],
"position": ["-1+math.cos(q.anim_time*90*12-180)*0.5", 0, 0]
},
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*12-40)*32", 0]
},
"wing_right_rotation": {
"rotation": ["10-math.cos(q.anim_time*90*12-25)*12", "10-(math.cos(q.anim_time*90*12-300)*55)", 0],
"position": ["1-math.cos(q.anim_time*90*12-180)*0.5", 0, 0]
},
"wing_right2": {
"rotation": [0, "-math.cos(q.anim_time*90*12-40)*32", 0]
},
"leg_left": {
"rotation": [73.00604, 3.91221, "65.7033-math.cos(q.anim_time*90*12-135)*4"]
},
"leg_left2": {
"rotation": [0, 0, "-52.5-math.cos(q.anim_time*90*12+45)*6"]
},
"leg_right": {
"rotation": [73.00604, -3.91221, "-65.7033+math.cos(q.anim_time*90*12-135)*4"]
},
"leg_right2": {
"rotation": [0, 0, "52.5+math.cos(q.anim_time*90*12+45)*6"]
},
"pupil_left": {
"scale": 1
},
"ear_left": {
"rotation": [-20, 0, 0],
"position": [0, 0.1, 0.2]
},
"ear_right": {
"rotation": [-20, 0, 0],
"position": [0, 0.1, 0.2]
},
"wing_left": {
"rotation": ["0-math.cos(q.anim_time*90*12-40)*8", "math.cos(q.anim_time*90*12+40)*42", 0]
},
"wing_left3": {
"rotation": [0, "math.cos(q.anim_time*90*12-90)*32", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*12-120)*18", 0]
},
"wing_right": {
"rotation": ["0-math.cos(q.anim_time*90*12-40)*8", "-math.cos(q.anim_time*90*12+40)*42", 0]
},
"wing_right3": {
"rotation": [0, "-math.cos(q.anim_time*90*12-90)*32", 0]
},
"wing_right4": {
"rotation": [0, "-math.cos(q.anim_time*90*12-120)*18", 0]
}
}
},
"animation.golbat.battle_idle": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"wing_left_rotation": {
"rotation": [0, "7.5+math.cos(q.anim_time*90*3-60)*6", -10],
"position": [-1, 0, 0]
},
"wing_left2": {
"rotation": [0, "15+math.cos(q.anim_time*90*3-120)*6", 0]
},
"legs": {
"rotation": [-17.5, 0, 0]
},
"leg_left": {
"rotation": ["33.4767-math.cos(q.anim_time*90*3)*2", "27.8672+math.cos(q.anim_time*90*3)*2", "30.7485-math.cos(q.anim_time*90*3)*4"]
},
"leg_left2": {
"rotation": [0, 10, "-5+math.cos(q.anim_time*90*3)*4.1"]
},
"toes_left": {
"rotation": [0, 0, -2.5]
},
"toes_inner_left": {
"rotation": [0, 0, -15]
},
"leg_right": {
"rotation": ["26.6423-math.cos(q.anim_time*90*3)*2", "-30.1083-math.cos(q.anim_time*90*3)*2", "-32.0409+math.cos(q.anim_time*90*3)*4"]
},
"leg_right2": {
"rotation": [0, 0, "25.2835-math.cos(q.anim_time*90*3)*4.1"]
},
"toes_right": {
"rotation": [0, 0, -10]
},
"toes_inner_right": {
"rotation": [0, 0, 5]
},
"body": {
"rotation": [9.6907, -12.73975, 0.31769],
"position": [0, "1.1-math.cos(q.anim_time*90*3)*0.26", "2+math.cos(q.anim_time*90*3)*0.06"]
},
"wing_left": {
"rotation": [5.22206, "-34.6575+math.cos(q.anim_time*90*3-30)*4", -9.13039]
},
"wing_right": {
"rotation": [5.22206, "34.6575-math.cos(q.anim_time*90*3-30)*4", 9.13039]
},
"wing_right_rotation": {
"rotation": [0, "-2.5-math.cos(q.anim_time*90*3-60)*6", 10],
"position": [1, 0, 0]
},
"wing_right2": {
"rotation": [0, "-15-math.cos(q.anim_time*90*3-120)*6", 0]
},
"tongue": {
"rotation": ["8.5+math.cos(q.anim_time*90*3-90)*4", 0, 0],
"position": [0, 0.5, 0],
"scale": [1, 1, 0.9]
},
"tongue2": {
"rotation": ["7.5+math.cos(q.anim_time*90*3-180)*6", 0, 0]
},
"torso": {
"rotation": ["1.5+math.cos(q.anim_time*90*3)*2", 0, 0],
"position": [0, 0, -0.8]
},
"pupil_left": {
"scale": 1
},
"mouth_closed": {
"position": [0, 0, 0]
},
"toes_outer_left": {
"rotation": [0, 0, -20]
},
"toes_outer_right": {
"rotation": [0, 0, 10]
},
"eye_left": {
"rotation": [0, 0, -5],
"position": [0, -0.1, 0]
},
"eye_right": {
"rotation": [0, 0, 5],
"position": [0, -0.1, 0]
},
"pupil_right": {
"position": [-0.5, 0, 0]
},
"wing_left3": {
"rotation": [0, "5+math.cos(q.anim_time*90*3-160)*6", 0]
},
"wing_left4": {
"rotation": [0, "5+math.cos(q.anim_time*90*3-200)*6", 0]
},
"wing_right3": {
"rotation": [0, "-5-math.cos(q.anim_time*90*3-160)*6", 0]
},
"wing_right4": {
"rotation": [0, "-5-math.cos(q.anim_time*90*3-200)*6", 0]
}
}
},
"animation.golbat.battle_idle_air": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"body": {
"rotation": ["math.cos(q.anim_time*90*12-135)*2", -12.7, "math.cos(q.anim_time*90*3)*1"],
"position": [
"math.cos(q.anim_time*90*3-45)*0.5",
"10+math.cos(q.anim_time*90*12)*0.5+math.cos(q.anim_time*90*6)*1.2",
"math.cos(q.anim_time*90*12)*0.25"
]
},
"tongue": {
"rotation": ["35+math.cos(q.anim_time*90*12+125)*6", "math.cos(q.anim_time*90*3)*8", 0],
"position": [0, 0.5, 0],
"scale": [1, 1, 0.9]
},
"tongue2": {
"rotation": ["math.cos(q.anim_time*90*12+35)*10", "math.cos(q.anim_time*90*3-90)*6", 0],
"position": [0, 0, 0.5]
},
"wing_left_rotation": {
"rotation": ["20-math.cos(q.anim_time*90*12-25)*24", "math.cos(q.anim_time*90*12-300)*55", 0],
"position": ["-1+math.cos(q.anim_time*90*12-180)*0.5", 0, 0]
},
"wing_left2": {
"rotation": [0, "math.cos(q.anim_time*90*12-40)*32", 0]
},
"wing_right_rotation": {
"rotation": ["20-math.cos(q.anim_time*90*12-25)*24", "-(math.cos(q.anim_time*90*12-300)*55)", 0],
"position": ["1-math.cos(q.anim_time*90*12-180)*0.5", 0, 0]
},
"wing_right2": {
"rotation": [0, "-math.cos(q.anim_time*90*12-40)*32", 0]
},
"leg_left": {
"rotation": [55.18392, "14.9084-math.cos(q.anim_time*90*3+45)*8", "60+math.cos(q.anim_time*90*3+45)*8"]
},
"leg_left2": {
"rotation": [0, 0, "-50-math.cos(q.anim_time*90*3+45)*6"]
},
"leg_right": {
"rotation": [55.18392, "-14.9084-math.cos(q.anim_time*90*3+45)*8", "-60+math.cos(q.anim_time*90*3+45)*8"]
},
"leg_right2": {
"rotation": [0, 0, "50-math.cos(q.anim_time*90*3+45)*6"]
},
"torso": {
"rotation": [30, 0, 0]
},
"pupil_right": {
"position": [-0.5, 0, 0]
},
"wings": {
"rotation": [15, 0, 0]
},
"wing_left": {
"rotation": ["0-math.cos(q.anim_time*90*12-40)*8", "math.cos(q.anim_time*90*12+40)*42", 0]
},
"wing_left3": {
"rotation": [0, "math.cos(q.anim_time*90*12-90)*32", 0]
},
"wing_left4": {
"rotation": [0, "math.cos(q.anim_time*90*12-120)*18", 0]
},
"wing_right": {
"rotation": ["0-math.cos(q.anim_time*90*12-40)*8", "-math.cos(q.anim_time*90*12+40)*42", 0]
},
"wing_right3": {
"rotation": [0, "-math.cos(q.anim_time*90*12-90)*32", 0]
},
"wing_right4": {
"rotation": [0, "-math.cos(q.anim_time*90*12-120)*18", 0]
}
}
},
"animation.golbat.sleep": {
"loop": true,
"bones": {
"body": {
"rotation": [90, 0, 0],
"position": [0, -5.75, 0]
"position": [0, -1.5, 6]
},
"rightwing": {
"rotation": [0, -7.5, 0]
"eyelid_left": {
"position": [0, 0, -0.1]
},
"leftwing": {
"rotation": [0, 7.5, 0]
"eyelid_right": {
"position": [0, 0, -0.1]
},
"rightleg": {
"rotation": [0, -37.5, 0]
"mouth_open": {
"position": [0, 0, 1]
},
"leftleg": {
"rotation": [0, 40, 0]
"mouth_closed": {
"position": [0, 0, -1]
},
"tongue": {
"rotation": [-90, 0, 0],
"position": [0, 0, 3]
},
"tongue2": {
"rotation": [-180, 0, 0],
"scale": [1, 1, 0.3]
},
"wing_left_rotation": {
"rotation": [0, 7.5, -17.5],
"position": [-2, 0, 0]
},
"wing_left2": {
"rotation": [0, -6.3, 0]
},
"wing_right_rotation": {
"rotation": [0, -7.5, 17.5],
"position": [2, 0, 0]
},
"wing_right2": {
"rotation": [0, 6.3, 0]
},
"leg_left": {
"rotation": [-17.8042, 9.84092, 26.9834]
},
"leg_left2": {
"rotation": [0, 0, -35]
},
"toes_inner_left": {
"rotation": [0, 0, -7.5]
},
"toes_outer_left": {
"rotation": [0, 0, 27.5]
},
"leg_right": {
"rotation": [-17.8042, -9.84092, -26.9834]
},
"leg_right2": {
"rotation": [0, 0, 35]
},
"toes_inner_right": {
"rotation": [0, 0, 7.5]
},
"toes_outer_right": {
"rotation": [0, 0, -27.5]
},
"wing_left": {
"rotation": [0, 10, 0]
},
"wing_left3": {
"rotation": [0, 0, 0]
},
"wing_left4": {
"rotation": [0, -4, 0]
},
"wing_right": {
"rotation": [0, -10, 0]
},
"wing_right3": {
"rotation": [0, 0, 0]
},
"wing_right4": {
"rotation": [0, 4, 0]
}
}
},
"animation.golbat.roost": {
"loop": true,
"animation_length": 2.5417,
"bones": {
"wing_left_rotation": {
"rotation": [0, 100, 0],
"position": [0, 1, 0]
},
"wing_left2": {
"rotation": [0, 80, 0]
},
"legs": {
"rotation": [-17.5, 0, 0]
},
"leg_left": {
"rotation": [14.28785, -17.54957, 49.81451]
},
"leg_left2": {
"rotation": [0, 0, -42.5]
},
"toes_left": {
"rotation": [0, 0, -2.5]
},
"toes_inner_left": {
"rotation": [0, 0, -15]
},
"leg_right": {
"rotation": [14.28785, 17.54957, -49.81451]
},
"leg_right2": {
"rotation": [0, 0, 42.5]
},
"toes_right": {
"rotation": [0, 0, 2.5]
},
"toes_inner_right": {
"rotation": [0, 0, 15]
},
"body": {
"rotation": [175, 180, 0],
"position": [0, 13, 0]
},
"wing_left": {
"rotation": [46.43569, 60.24584, 50.45318]
},
"wing_right": {
"rotation": [30.31658, -59.80983, -36.72517]
},
"wing_right_rotation": {
"rotation": [-181.50233, -77.49811, 176.50708],
"position": [0, 0, 0],
"scale": [1, 1, 0.7]
},
"wing_right2": {
"rotation": [0, -62.5, 0]
},
"tongue": {
"rotation": [-90, 0, 0],
"position": [0, 0, 3]
},
"tongue2": {
"rotation": [-180, 0, 0],
"scale": [1, 1, 0.3]
},
"torso": {
"rotation": ["5+math.cos(q.anim_time*90*1.5)*1.5", 0, 0]
},
"pupil_left": {
"scale": 1
},
"mouth_closed": {
"position": [0, 0, -1]
},
"toes_outer_left": {
"rotation": [0, 0, -10]
},
"toes_outer_right": {
"rotation": [0, 0, 10]
},
"mouth_open": {
"position": [0, 0, 1]
},
"wings": {
"rotation": [0, 0, 0],
"position": [0, -2, 0],
"scale": [1, 1, 0.5]
},
"wing_left3": {
"rotation": [0, 65, 0]
},
"wing_left4": {
"rotation": [0, 32.5, 0]
},
"wing_right3": {
"rotation": [0, -62.5, 0]
},
"wing_right4": {
"rotation": [0, -45, 0]
}
}
},
"animation.golbat.blink": {
"animation_length": 0.16667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.golbat.cry": {
"animation_length": 1.5,
"bones": {
"torso": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [10, 0, 0],
"0.0833": [-10, 0, 0],
"0.4167": ["-12.5+math.cos(q.anim_time*90*80)*2", 0, 0],
"0.5": [-2.5, 0, 0],
"0.5833": [2, 0, 0],
"0.6667": [3.05, 0, 0],
"0.7917": [2.77, 0, 0],
"0.9167": [2.03, 0, 0],
"1.0417": [1.04, 0, 0],
"1.1667": [0.59, 0, 0],
"1.25": [0.27, 0, 0],
"1.3333": [0, 0, 0],
"1.5": [0, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.0417": [0, 0, -0.1],
"0.0833": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.0417": [0, 0, -0.1],
"0.0833": [0, 0, 0]
}
},
"mouth_back": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 4, 0],
"0.0833": [0, 0, 0],
"0.4583": [0, 0, 0],
"0.5417": [0, 4, 0],
"0.5833": [0, 1.75, 0],
"0.7083": [0, 0, 0]
},
"scale": {
"0.0": [1, 1, 1],
"0.0417": [1, 0.5, 1],
"0.0833": [1, 1, 1],
"0.4583": [1, 1, 1],
"0.5417": [1, 0.6, 1],
"0.5833": [1, 0.825, 1],
"0.7083": [1, 1, 1]
}
},
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 7, 0],
"0.0833": [0, 0, 0],
"0.4583": [0, 0, 0],
"0.5417": [0, 7, 0],
"0.5833": [0, 3, 0],
"0.7083": [0, 0, 0]
}
},
"tongue": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 5.5, 0],
"0.0833": [0, 0, 0],
"0.4583": [0, 0, 0],
"0.5417": [0, 5, 0],
"0.625": [0, 1, 0],
"0.7083": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.golbat.cry"
}
}
},
"animation.golbat.crytongue": {
"animation_length": 0.70833,
"bones": {
"tongue": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, 0],
"0.125": ["math.cos(q.anim_time*90*24)*12", 0, 0],
"0.5417": ["math.cos(q.anim_time*90*24)*12", 0, 0],
"0.625": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, 0],
"0.125": [0, 0, 0],
"0.5417": [0, 0, 0],
"0.625": [0, 0, 0]
}
},
"tongue2": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [0, 0, 0],
"0.125": ["math.cos(q.anim_time*90*24-90)*24", 0, 0],
"0.375": ["math.cos(q.anim_time*90*24-90)*24", 0, 0],
"0.4583": [0, 0, 0]
}
}
}
}

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