Compare commits

...
Author SHA1 Message Date
Sterrezo b2f002d630 Update PosableState.kt 2026-10-03 14:44:28 +02:00
Polymeta 5b9d5cbb55 [skip-ci] tidy up changelog
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-02 08:34:22 +01:00
Polymeta ff890307c2 Merge branch 'feature/change-the-rules' into 'main'
change how item interaction evolutions are processed

Closes #1864 and #1874

See merge request cable-mc/cobblemon!2399
2026-10-02 07:07:29 +00:00
Polymeta dda9d3e790 [skip-ci] tidy up changelog
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-02 08:02:57 +01:00
Polymeta 1acc02a2ec Merge branch 'more-block-noises' into 'main'
Added sounds for liquid bottle, pill bottle and dice blocks

See merge request cable-mc/cobblemon!2441
2026-10-02 06:56:17 +00:00
Jackson Bowes 9a036a4c01 Merge branch 'implement_pokemon' into 'main'
implement_pokemon

See merge request cable-mc/cobblemon!2439
2026-10-01 22:48:51 -05:00
Sterrezo 3cea6dd175 Forgot powders 2026-10-01 19:03:52 +02:00
Sterrezo 2fa053f833 Update CHANGELOG.md 2026-10-01 18:55:35 +02:00
Sterrezo ea4f858919 Added sounds for liquid bottle, pill bottle and dice blocks 2026-10-01 18:53:06 +02:00
Polymeta d86021e2a1 Merge branch 'fix/safari-ball-catchrate' into 'main'
fix: change safari ball catchrate modifier

See merge request cable-mc/cobblemon!2440
2026-10-01 05:26:45 +00:00
JakotensandJakotens 79faadef59 Slight texture updates to Sudowoodo.
Signed-off-by: Jakotens <jjakobdupuyy@gmail.com>
2026-09-30 19:54:48 -06:00
Gitoido 9b6629db7f chore: update changelog skip-ci 2026-10-01 02:47:45 +03:00
Gitoido d151a1ce65 fix: change safari ball catchrate modifier
Changed safari ball catchrate modifier to properly account for battle status
2026-10-01 02:44:20 +03:00
ewwww d9ca7b483d tweaked sudowoodo textures 2026-09-30 19:40:29 -04:00
Instrafe 708f7fc1b8 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2026-09-30 18:59:11 -04:00
Instrafe 621db85845 The evolution knows where it is because it knows where it isn't 2026-09-30 18:59:01 -04:00
Instrafe b09066c580 Added negate tags to regional and Vivillon evolutions to prevent biome overlap 2026-09-30 18:58:23 -04:00
ewwww 7c45f28827 ekans remodel + animations 2026-09-30 13:39:45 -04:00
ewwww 9c1b2cae22 vikavolt fixed placeholder animations 2026-09-30 08:59:25 -04:00
ewwww 16b2f81bd4 arbok animations 2026-09-30 08:57:47 -04:00
Jackson Bowes 108f0e3d88 Merge branch 'pokemon-return-update' into 'main'
Pokeball Recall and Capture FX Improvement

See merge request cable-mc/cobblemon!2317
2026-09-29 19:44:15 -05:00
Plastered_CrabandJackson Bowes 4344c127eb Pokeball Recall and Capture FX Improvement 2026-09-29 19:44:15 -05:00
Polymeta 5955547c6f Merge branch 'evolution-tree' into 'main'
Evolution tree

See merge request cable-mc/cobblemon!2385
2026-09-29 10:14:09 +00:00
lionandPolymeta 7a3a1cb8de Evolution tree 2026-09-29 10:14:09 +00:00
Polymeta 1674cb0913 fix typo
Closes #2115
2026-09-29 06:44:27 +00:00
Polymeta 152ce4e923 Merge branch 'shoulder-mount-armor-clipping' into 'main'
Shoulder Mount Enhancements

See merge request cable-mc/cobblemon!2410
2026-09-29 06:42:36 +00:00
BreezyashaandPolymeta 3a6d024217 Shoulder Mount Enhancements 2026-09-29 06:42:36 +00:00
Polymeta f2fcc5ba79 Merge branch 'implement_pokemon' into 'main'
implement_pokemon

Closes #2106

See merge request cable-mc/cobblemon!2428
2026-09-28 20:25:03 +00:00
RedGenesectNinja db0fb8e287 Added implemented flag to Tympole, Palpitoad and Seismitoad 2026-09-28 15:06:55 -05:00
Jerzykv dae36a67d1 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2026-09-28 19:11:43 +02:00
JakotensandJerzykv 6f99862288 Fixed some small texture issues on Pidgeot.
Signed-off-by: Jakotens <jjakobdupuyy@gmail.com>
2026-09-28 19:11:27 +02:00
Jerzykv 0377747e1e implemented flag 2026-09-28 19:11:26 +02:00
Polymeta 6bc974f90f Merge branch 'keyframe-super-ghostbusters' into 'main'
Fix for doubled effect keyframes

Closes #2107

See merge request cable-mc/cobblemon!2436
2026-09-28 13:14:51 +00:00
Sterrezo aca53de259 Update CHANGELOG.md 2026-09-28 14:50:24 +02:00
Sterrezo 41bde38727 Fixed effect keyframes sometimes getting doubled probably 2026-09-28 14:49:06 +02:00
Polymeta a4b7ee3b38 follow-up fix from registry change
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-09-28 09:01:58 +01:00
JakotensandJakotens 154b653c57 Fixed some small texture issues on Pidgeot.
Signed-off-by: Jakotens <jjakobdupuyy@gmail.com>
2026-09-27 17:33:09 -06:00
Jerzykv 04489bc969 changelog 2026-09-27 12:39:00 +02:00
Jerzykv 25499b3e7a Fixed #2106 2026-09-27 12:37:49 +02:00
Instrafe bb6bda54dc Updated Changelog 2026-09-26 14:17:30 -04:00
Instrafe 9f3dbdc2d8 Implemented remodel for Shroomish 2026-09-26 14:13:33 -04:00
JakotensandJakotens 932148338c Added animations for Treecko and Bonsly. Added remodel and animations for Sudowoodo.
Signed-off-by: Jakotens <jjakobdupuyy@gmail.com>
2026-09-25 23:05:21 -06:00
Jerzykv 309f674853 Implemented Minior 2026-09-24 13:38:30 +02:00
Jerzykv dc705c7720 Fixed Alolan Diglett's cry 2026-09-24 09:48:23 +02:00
ewwww 9bfc577444 oddish, gloom, vileplume, and bellossom remodels + animations 2026-09-22 04:35:07 -04:00
ewwww 3ca6d350fe these were forgotten 2026-09-21 11:40:14 -04:00
Instrafe 2997ce8457 Updated Changelog 2026-09-21 09:54:23 -04:00
Instrafe ff279d8310 Poliwag and Politoed now have remodels + Implemented gender differences for Politoed 2026-09-21 09:53:53 -04:00
Polymeta 91d6fb62ba dedicated handling for forced evolutions, those take priority and only one at a time
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-09-21 09:18:06 +01:00
Polymeta 8f4a5b2015 fix typo in changelog 2026-09-21 09:18:06 +01:00
Polymeta 07604c9a3b change how item interaction evolutions are processed
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-09-21 09:18:06 +01:00
258 changed files with 34369 additions and 8555 deletions
+46 -2
View File
@@ -13,6 +13,8 @@
- Galarica Wreath, Cleanse Tag, Spell Tag, Sharp Beak, Covert Cloak, Shell Helmet, and Never-Melt Ice.
- Wearable items can now be equipped by a player by holding it and right-clicking (or rebound use/interact)
- Wearable items that can be placed down are exempt from this behaviour.
- The evolution tree can now be viewed on the Pokédex, showing a Pokémon's full family line and what's needed to evolve into each stage.
- Added custom sounds to a bunch of items that can be placed as blocks: liquid bottles, pill bottles, powders and dice.
### Pokémon Added
#### Generation 4
@@ -35,12 +37,18 @@
- Grubbin
- Charjabug
- Vikavolt
- Minior
#### Generation 8
- Eternatus
#### Generation 9
- Greavard
- Houndstone
### Model updates for the following Pokémon
- Sudowoodo
- Spheal
- Cacnea
- Cacturne
- Binacle
@@ -50,10 +58,27 @@
- Deerling
- Sawsbuck (All forms)
- Absol
- Poliwag
- Politoed
- Ekans
- Oddish
- Gloom
- Vileplume
- Bellossom
- Shroomish
### Animation updates for the following Pokémon
- Treecko (New Shoulder Mount!)
- Bonsly (New Shoulder Mount!)
- Sudowoodo
- Cacnea
- Cacturne
- Ekans
- Arbok
- Oddish
- Gloom
- Vileplume
- Bellossom
### Changes
- Updated various recipes to display in Recipe Groups within the Recipe Book
@@ -61,9 +86,15 @@
- Make ride rotations less jittery in multiplayer.
- Changes tm shelf discs to use textures instead of tinting and overlays to line up with item display
- Blank TM can now be inserted into the Disc Shelf
- Recall animation now renders ball in hand with the player arm raised.
- Made regional and Vivillon split-evo locations now mutually exclusive
- Item evolutions now unlock **all** locked evolutions whose requirements are met instead of stopping after the first.
- Exceptions being "forced" evolutions which will continue to stop after the first one
### Fixes
- Correctly grants "They're Minerals!" advancement when planting a type gem
- Shoulder mounted Pokémon now follow player body animations, improving their positioning with custom player animations and default actions.
- Shoulder mounted Pokémon now sit slightly higher with chest armor equipped for better alignment, with a configurable blacklist.
- Type Gem Blocks now have advancements to give you the recipe in the recipe book (the data for the advancements were inside the recipes somehow??)
- Some other recipes without advancements have also been corrected
- Corrected the TM Recipes for Charge Beam and Payday
@@ -82,10 +113,23 @@
- Fixed Duraludon line not having any sleep animations
- Fixed Diglett line not having their faint animations
- Fixed Kingambit moving its legs while walking
- Fixed Alolan Diglett's cry not playing
- Fixed shiny alpha Snorlax using the non-shiny texture
- Various Structure fixes
- Fixed shiny pokemon under certain circumstances forgetting taught TMs
- Fixed shiny Pokémon under certain circumstances forgetting taught TMs
- Fixed certain Pokémon sounds sometimes being doubled when played at specific times in their animations
- Fixed ball capture beam origin coming from behind the ball.
- Fixed Safari Ball catch rate outside of battle
### Developer
- Evolution requirements can now set `pokedexIcon` and `pokedexTooltip` directly in their JSON to control how they're shown on the Pokédex's evolution tree, for example:
```json
{
"variant": "attack_defence_ratio",
"pokedexIcon": "minecraft:diamond_sword",
"pokedexTooltip": "cobblemon.ui.pokedex.requirement.attack_defence_ratio.tooltip"
}
```
- Fixed wrong order of operations in the code flow prior to the `FOSSIL_REVIVED` event causing pokemon to appear without entity link
- Fixed TestPartySlot command not correctly comparing the provided spec with the target Pokémon
@@ -98,4 +142,4 @@
#### New Move Animations
### Localization
- Updated translations for:
- Updated translations for:
@@ -10,11 +10,13 @@ package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.client.render.player.MountedPlayerRenderer;
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
import com.cobblemon.mod.common.duck.RidePassenger;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import org.spongepowered.asm.mixin.Final;
@@ -96,4 +98,14 @@ public class HumanoidModelMixin {
MountedPlayerRenderer.INSTANCE.animate((HumanoidModel<AbstractClientPlayer>)(Object)this, pokemonEntity, player, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
}
}
@Inject(method = "setupAnim*", at = @At("TAIL"))
public void cobblemon$poseRecallArm(LivingEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, CallbackInfo ci) {
if (!(entity instanceof AbstractClientPlayer) || entity.getVehicle() instanceof PokemonEntity) return;
float raise = RecallArmAnimationTracker.INSTANCE.raiseFactor(entity.getUUID());
if (raise <= 0f) return;
this.rightArm.xRot = Mth.lerp(raise, this.rightArm.xRot, (float) (-Math.PI / 2.0));
this.rightArm.yRot = Mth.lerp(raise, this.rightArm.yRot, 0f);
this.rightArm.zRot = Mth.lerp(raise, this.rightArm.zRot, 0f);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ItemInHandLayer.class)
public class ItemInHandLayerMixin {
@Inject(method = "renderArmWithItem", at = @At("HEAD"), cancellable = true)
private void cobblemon$hideRecallHandItem(LivingEntity entity, ItemStack itemStack, ItemDisplayContext itemDisplayContext, HumanoidArm humanoidArm, PoseStack poseStack, MultiBufferSource multiBufferSource, int light, CallbackInfo ci) {
if (humanoidArm == HumanoidArm.RIGHT && RecallArmAnimationTracker.INSTANCE.isRecalling(entity.getUUID())) {
ci.cancel();
}
}
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.client.render.player.FirstPersonRecallBallRenderer;
import com.cobblemon.mod.common.item.PokedexItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
@@ -31,6 +32,9 @@ public class ItemInHandRendererMixin {
if (abstractClientPlayer.isUsingItem() && abstractClientPlayer.getUseItem().getItem() instanceof PokedexItem) {
ci.cancel();
}
else if (interactionHand == InteractionHand.MAIN_HAND && FirstPersonRecallBallRenderer.INSTANCE.render(poseStack, multiBufferSource, j, f)) {
ci.cancel();
}
else if (abstractClientPlayer instanceof OrientationControllable controllable && controllable.getOrientationController().isActive()) {
}
@@ -657,11 +657,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACHET = create("sachet", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOL).mapColor(MapColor.NONE).noOcclusion(), DecorativeItemBlock.DecorativeItemBlockType.POUCH))
@JvmField
val METAL_POWDER = create("metal_powder", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOL).mapColor(MapColor.NONE).noOcclusion(), DecorativeItemBlock.DecorativeItemBlockType.POUCH))
val METAL_POWDER = create("metal_powder", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_POWDER_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), DecorativeItemBlock.DecorativeItemBlockType.POUCH))
@JvmField
val QUICK_POWDER = create("quick_powder", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOL).mapColor(MapColor.NONE).noOcclusion(), DecorativeItemBlock.DecorativeItemBlockType.POUCH))
val QUICK_POWDER = create("quick_powder", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_POWDER_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), DecorativeItemBlock.DecorativeItemBlockType.POUCH))
@JvmField
val BRIGHT_POWDER = create("bright_powder", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOL).mapColor(MapColor.NONE).noOcclusion().lightLevel{3}, DecorativeItemBlock.DecorativeItemBlockType.POUCH))
val BRIGHT_POWDER = create("bright_powder", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_POWDER_SOUNDS).mapColor(MapColor.NONE).noOcclusion().lightLevel{3}, DecorativeItemBlock.DecorativeItemBlockType.POUCH))
@JvmField
val NEVER_MELT_ICE = create("never_melt_ice", DecorativeItemBlock(BlockBehaviour.Properties.of().sound(SoundType.GLASS).mapColor(MapColor.NONE).noOcclusion().friction(0.989F), DecorativeItemBlock.DecorativeItemBlockType.NEVERMELT))
@@ -691,7 +691,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val EJECT_BUTTON = create("eject_button", EjectButtonBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.NONE).pushReaction(PushReaction.DESTROY).noOcclusion().strength(0.125f), 40))
@JvmField
val LOADED_DICE = create("loaded_dice", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.DICE))
val LOADED_DICE = create("loaded_dice", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_DICE_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.DICE))
@JvmField
val IRON_BALL = create("iron_ball", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.METAL).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.IRON_BALL))
@JvmField
@@ -702,40 +702,40 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val DUBIOUS_DISC = create("dubious_disc", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.UPGRADE))
@JvmField
val THROAT_SPRAY = create("throat_spray", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.THROAT_SPRAY))
val THROAT_SPRAY = create("throat_spray", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.THROAT_SPRAY))
@JvmField
val FULL_HEAL = create("full_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
val FULL_HEAL = create("full_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val ANTIDOTE = create("antidote", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
val ANTIDOTE = create("antidote", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val AWAKENING = create("awakening", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
val AWAKENING = create("awakening", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val BURN_HEAL = create("burn_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
val BURN_HEAL = create("burn_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val ICE_HEAL = create("ice_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
val ICE_HEAL = create("ice_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val PARALYZE_HEAL = create("paralyze_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
val PARALYZE_HEAL = create("paralyze_heal", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.STATUS_RESTORE))
@JvmField
val ETHER = create("ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
val ETHER = create("ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val MAX_ETHER = create("max_ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
val MAX_ETHER = create("max_ether", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val ELIXIR = create("elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
val ELIXIR = create("elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val MAX_ELIXIR = create("max_elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
val MAX_ELIXIR = create("max_elixir", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.ETHER))
@JvmField
val POTION = create("potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
val POTION = create("potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
@JvmField
val SUPER_POTION = create("super_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
val SUPER_POTION = create("super_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
@JvmField
val HYPER_POTION = create("hyper_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
val HYPER_POTION = create("hyper_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.POTION))
@JvmField
val MAX_POTION = create("max_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
val MAX_POTION = create("max_potion", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
@JvmField
val FULL_RESTORE = create("full_restore", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
val FULL_RESTORE = create("full_restore", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.MAX_POTION))
@JvmField
val DIRE_HIT = create("dire_hit", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@@ -755,21 +755,21 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val X_SPEED = create("x_${Stats.SPEED.identifier.path}", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.BATTLE_ITEM))
@JvmField
val HP_UP = create("hp_up", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val HP_UP = create("hp_up", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val PROTEIN = create("protein", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val PROTEIN = create("protein", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val IRON = create("iron", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val IRON = create("iron", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val CARBOS = create("carbos", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val CARBOS = create("carbos", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val CALCIUM = create("calcium", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val CALCIUM = create("calcium", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val ZINC = create("zinc", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val ZINC = create("zinc", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val PP_UP = create("pp_up", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val PP_UP = create("pp_up", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val PP_MAX = create("pp_max", StackableItemBlock(BlockBehaviour.Properties.of().sound(SoundType.CANDLE).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
val PP_MAX = create("pp_max", StackableItemBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.ITEM_BLOCK_BOTTLE_PILLS_SOUNDS).mapColor(MapColor.NONE).noOcclusion(), StackableItemBlock.StackableItemBlockType.VITAMIN))
@JvmField
val MONITOR = create("monitor", MonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 13 else 0 }))
@@ -425,6 +425,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpeciesEvolutionSyncPacket.ID, SpeciesEvolutionSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(PropertiesCompletionRegistrySyncPacket.ID, PropertiesCompletionRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(StandardSpeciesFeatureSyncPacket.ID, StandardSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(GlobalSpeciesFeatureSyncPacket.ID, GlobalSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler()))
@@ -657,5 +657,65 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
SoundEvents.WOOL_FALL
)
@JvmField
val ITEM_BLOCK_POWDER_PLACE = this.create("block.item_block.powder.place")
@JvmField
val ITEM_BLOCK_POWDER_BREAK = this.create("block.item_block.powder.break")
@JvmField
val ITEM_BLOCK_POWDER_STEP = this.create("block.item_block.powder.step")
@JvmField
val ITEM_BLOCK_POWDER_SOUNDS = SoundType(1f, 1.1f,
ITEM_BLOCK_POWDER_BREAK,
ITEM_BLOCK_POWDER_STEP,
ITEM_BLOCK_POWDER_PLACE,
ITEM_BLOCK_POWDER_STEP,
ITEM_BLOCK_POWDER_STEP
)
@JvmField
val ITEM_BLOCK_BOTTLE_LIQUID_PLACE = this.create("block.item_block.bottle_liquid.place")
@JvmField
val ITEM_BLOCK_BOTTLE_LIQUID_BREAK = this.create("block.item_block.bottle_liquid.break")
@JvmField
val ITEM_BLOCK_BOTTLE_LIQUID_STEP = this.create("block.item_block.bottle_liquid.step")
@JvmField
val ITEM_BLOCK_BOTTLE_LIQUID_SOUNDS = SoundType(1f, 1.1f,
ITEM_BLOCK_BOTTLE_LIQUID_BREAK,
ITEM_BLOCK_BOTTLE_LIQUID_STEP,
ITEM_BLOCK_BOTTLE_LIQUID_PLACE,
ITEM_BLOCK_BOTTLE_LIQUID_PLACE,
ITEM_BLOCK_BOTTLE_LIQUID_PLACE
)
@JvmField
val ITEM_BLOCK_BOTTLE_PILLS_PLACE = this.create("block.item_block.bottle_pills.place")
@JvmField
val ITEM_BLOCK_BOTTLE_PILLS_BREAK = this.create("block.item_block.bottle_pills.break")
@JvmField
val ITEM_BLOCK_BOTTLE_PILLS_STEP = this.create("block.item_block.bottle_pills.step")
@JvmField
val ITEM_BLOCK_BOTTLE_PILLS_SOUNDS = SoundType(1f, 1.1f,
ITEM_BLOCK_BOTTLE_PILLS_BREAK,
ITEM_BLOCK_BOTTLE_PILLS_STEP,
ITEM_BLOCK_BOTTLE_PILLS_PLACE,
ITEM_BLOCK_BOTTLE_PILLS_PLACE,
ITEM_BLOCK_BOTTLE_PILLS_PLACE
)
@JvmField
val ITEM_BLOCK_DICE_PLACE = this.create("block.item_block.dice.place")
@JvmField
val ITEM_BLOCK_DICE_BREAK = this.create("block.item_block.dice.break")
@JvmField
val ITEM_BLOCK_DICE_STEP = this.create("block.item_block.dice.step")
@JvmField
val ITEM_BLOCK_DICE_SOUNDS = SoundType(1f, 1.1f,
ITEM_BLOCK_DICE_BREAK,
ITEM_BLOCK_DICE_STEP,
ITEM_BLOCK_DICE_PLACE,
ITEM_BLOCK_DICE_STEP,
ITEM_BLOCK_DICE_STEP
)
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.createVariableRangeEvent(cobblemonResource(name)))
}
@@ -11,6 +11,9 @@ package com.cobblemon.mod.common.api.conditional
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
/**
@@ -21,11 +24,19 @@ import java.lang.reflect.Type
* @author Hiroku
* @since July 17th, 2022
*/
interface RegistryLikeAdapter<B> : JsonDeserializer<RegistryLikeCondition<B>> {
interface RegistryLikeAdapter<B> : JsonDeserializer<RegistryLikeCondition<B>>, JsonSerializer<RegistryLikeCondition<B>> {
val registryLikeConditions: MutableList<(JsonElement) -> RegistryLikeCondition<B>?>
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): RegistryLikeCondition<B> {
return registryLikeConditions.firstNotNullOfOrNull { it(json) }
?: throw IllegalArgumentException("Unable to deserialize $json")
}
override fun serialize(src: RegistryLikeCondition<B>, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
return when (src) {
is RegistryLikeTagCondition<B> -> JsonPrimitive(RegistryLikeTagCondition.PREFIX + src.tag.location())
is RegistryLikeIdentifierCondition<B> -> JsonPrimitive(src.identifier.toString())
else -> throw IllegalArgumentException("Unable to serialize $src")
}
}
}
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.gui
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
import net.minecraft.client.gui.components.AbstractWidget
import net.minecraft.client.gui.components.Renderable
import net.minecraft.client.gui.components.events.GuiEventListener
import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.network.chat.Component
@@ -55,6 +54,8 @@ abstract class ParentWidget(
}
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
if (!active) return false
return children.any {
it.mouseClicked(pMouseX, pMouseY, pButton)
}
@@ -0,0 +1,116 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.gui
import kotlin.math.max
import kotlin.math.min
interface TreeNode<T> {
val children: List<TreeNode<T>>
}
class TreeDrawingNode<T>(
val value: T,
val children: List<TreeDrawingNode<T>>,
) {
var x = 0
var y = 0
var offset = 0
}
fun <T> createDrawingTree(treeNode: TreeNode<T>): TreeDrawingNode<T> {
val root = setup(treeNode, 0, mutableListOf<Int>(), mutableListOf<Int>())
addMods(root, 0)
return root
}
@Suppress("UNCHECKED_CAST")
private fun <T> setup(
treeNode: TreeNode<T>,
depth: Int,
nexts: MutableList<Int>,
offset: MutableList<Int>,
): TreeDrawingNode<T> {
val children = treeNode.children.map { child ->
setup(child, depth + 1, nexts, offset)
}
val treeDrawingNode = TreeDrawingNode<T>(treeNode as T, children)
treeDrawingNode.y = depth
while (nexts.size <= depth) {
nexts.add(0)
}
while (offset.size <= depth) {
offset.add(0)
}
var place =
if (children.isEmpty()) {
nexts[depth]
} else if (children.size == 1) {
// children.first().x - 1
children.first().x
} else {
// (children[0].x + children[1].x) / 2
(children.first().x + children.last().x) / 2
}
offset[depth] = max(offset[depth], nexts[depth] - place)
if (children.isEmpty()) {
treeDrawingNode.x = place
} else {
treeDrawingNode.x = place + offset[depth]
}
nexts[depth] += 2
treeDrawingNode.offset = offset[depth]
return treeDrawingNode
}
private fun <T> addMods(
treeNode: TreeDrawingNode<T>,
modSum: Int,
) {
treeNode.x += modSum
val newModSum = modSum + treeNode.offset
treeNode.children.forEach { child ->
addMods(child, newModSum)
}
}
data class TreeDrawingBounds(val minX: Int, val maxX: Int, val minY: Int, val maxY: Int) {
val width = maxX - minX
val height = maxY - minY
val xCenter = (maxX + minX) / 2.0
val yCenter = (maxY + minY) / 2.0
}
fun <T> calculateBounds(treeDrawingNode: TreeDrawingNode<T>): TreeDrawingBounds {
var minX = treeDrawingNode.x
var maxX = treeDrawingNode.x
var minY = treeDrawingNode.y
var maxY = treeDrawingNode.y
for (child in treeDrawingNode.children) {
val childBounds = calculateBounds(child)
minX = min(minX, childBounds.minX)
maxX = max(maxX, childBounds.maxX)
minY = min(minY, childBounds.minY)
maxY = max(maxY, childBounds.maxY)
}
return TreeDrawingBounds(minX, maxX, minY, maxY)
}
@@ -108,7 +108,7 @@ object CatchRateModifiers {
* Used by [PokeBalls.SAFARI_BALL].
* Checks if the target is not battling, if true boost by *1.5
*/
val SAFARI = WorldStateModifier { _, entity -> if (!entity.isBattling) 1.5F else 1F }
val SAFARI = MultiplierModifier(1.5f) { _, poke -> !poke.entity?.isBattling!! }
/**
* Used by [PokeBalls.PARK_BALL].
@@ -13,6 +13,10 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.pokemon.feature.ChoiceSpeciesFeatureProvider
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
import com.cobblemon.mod.common.api.pokemon.feature.WeightedChoiceSpeciesFeatureProvider
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
import com.cobblemon.mod.common.pokemon.Gender
import net.minecraft.resources.ResourceLocation
@@ -72,6 +76,57 @@ abstract class AbstractPokedexManager {
} ?: PokedexEntryProgress.UNREGISTERED
}
fun getHighestKnowledgeFor(entry: PokedexEntry, form: PokedexForm?): PokedexEntryProgress {
if (form == null) return getHighestKnowledgeFor(entry)
val speciesRecord = getSpeciesRecord(entry.speciesId) ?: return PokedexEntryProgress.UNREGISTERED
val hasAllAspects = entry.conditionAspects.all(speciesRecord::hasAspect)
if (!hasAllAspects) {
return PokedexEntryProgress.UNREGISTERED
}
return speciesRecord.getFormRecord(form.displayForm)?.knowledge ?: PokedexEntryProgress.UNREGISTERED
}
fun getHighestKnowledgeFor(entry: PokedexEntry, form: PokedexForm?, aspects: Iterable<String>): PokedexEntryProgress {
val formKnowledge = getHighestKnowledgeFor(entry, form)
if (formKnowledge == PokedexEntryProgress.UNREGISTERED) return PokedexEntryProgress.UNREGISTERED
val seenAspects = getSeenAspects(entry)
// Aspects that select one of the species' own forms are already covered by the form knowledge check above,
// so exempt them (and every other value of the same feature, since defaults like "phony" never appear on a form directly).
val species = PokemonSpecies.getByIdentifier(entry.speciesId)
val formAspects = species?.forms?.flatMapTo(hashSetOf()) { it.aspects } ?: emptySet()
val formSelectingFeatureAspects = species?.let(SpeciesFeatures::getFeaturesFor).orEmpty()
.mapNotNull { provider ->
val allAspects: Collection<String> = when (provider) {
is ChoiceSpeciesFeatureProvider -> provider.getAllAspects()
is WeightedChoiceSpeciesFeatureProvider -> provider.getAllAspects().keys
else -> return@mapNotNull null
}
allAspects.takeIf { it.any { aspect -> aspect in formAspects } }
}
.flatten()
.toHashSet()
val allSeenAspects = aspects
.filter { aspect ->
if (Dexes.equivalentFormsLookup[aspect] != null) return@filter false
if (aspect in formAspects || aspect in formSelectingFeatureAspects) return@filter false
if (aspect.uppercase() in setOf(Gender.MALE.name, Gender.FEMALE.name, Gender.GENDERLESS.name)) return@filter false
if ("shiny".equals(aspect, ignoreCase = true)) return@filter false
return@filter true
}
.all { aspect -> seenAspects.contains(aspect) }
if (!allSeenAspects) return PokedexEntryProgress.UNREGISTERED
return formKnowledge
}
fun getEncounteredForms(entry: PokedexEntry) : List<PokedexForm> {
return getFormsWithKnowledge(entry, PokedexEntryProgress.SEEN)
}
@@ -10,6 +10,9 @@ package com.cobblemon.mod.common.api.pokedex
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.pokedex.def.PokedexDef
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.PokedexDexSyncPacket
import com.cobblemon.mod.common.util.adapters.CodecBackedAdapter
@@ -40,6 +43,17 @@ object Dexes : JsonDataRegistry<PokedexDef> {
//Maps a dex id to its PokedexDef
val dexEntryMap = linkedMapOf<ResourceLocation, PokedexDef>()
val equivalentForms = mapOf(
"galar" to listOf("region-bias-galar", "bias-galar", "galar-bias", "galarian", "galar"),
"alola" to listOf("region-bias-alola", "bias-alola", "alola-bias", "alolan", "alola"),
"hisui" to listOf("region-bias-hisui", "bias-hisui", "hisui-bias", "hisuian", "hisui"),
"paldea" to listOf("region-bias-paldea", "bias-paldea", "paldea-bias", "paldean", "paldea"),
)
val equivalentFormsLookup = equivalentForms.flatMap { (key, values) ->
values.map { it to key }
}.toMap()
override fun reload(data: Map<ResourceLocation, PokedexDef>) {
dexEntryMap.clear()
data.entries.sortedBy { it.value.sortOrder }.forEach { (id, def) -> dexEntryMap[id] = def }
@@ -49,4 +63,41 @@ object Dexes : JsonDataRegistry<PokedexDef> {
override fun sync(player: ServerPlayer) {
PokedexDexSyncPacket(dexEntryMap.values).sendToPlayer(player)
}
fun findDexEntryBySpeciesId(regionId: ResourceLocation, speciesId: ResourceLocation): PokedexEntry? {
return dexEntryMap[regionId]?.getEntries()?.firstOrNull { it -> it.speciesId == speciesId }
}
fun findDexEntryBySpeciesId(speciesId: ResourceLocation): PokedexEntry? {
return findDexEntryBySpeciesId(cobblemonResource("national"), speciesId)
}
fun findRootDexEntryBySpeciesId(speciesId: ResourceLocation, formName: String): Pair<PokedexEntry, PokedexForm> {
var rootSpecies = PokemonSpecies.getByIdentifier(speciesId)!!
val initialFormEquivalents = getFormEquivalents(formName)
var rootForm = rootSpecies.forms.firstOrNull { initialFormEquivalents.contains(it.name.lowercase()) }
?: rootSpecies.standardForm
var preEvolution = rootForm.preEvolution
while (preEvolution != null) {
rootSpecies = preEvolution.species
rootForm = preEvolution.resolveForm(rootForm.aspects.toSet())
preEvolution = rootForm.preEvolution
}
val entry = findDexEntryBySpeciesId(rootSpecies.resourceIdentifier)
?: throw RuntimeException("Root dex entry not found")
val formEquivalents = getFormEquivalents(rootForm.name)
val form =
entry.forms.firstOrNull { formEquivalents.contains(it.displayForm.lowercase()) } ?:
entry.forms.first { it.displayForm.equals("Normal", ignoreCase = true) }
return entry to form
}
fun getFormEquivalents(formName: String): List<String> {
val key = equivalentFormsLookup[formName.lowercase()]
return equivalentForms[key] ?: listOf(formName.lowercase())
}
}
@@ -121,6 +121,7 @@ class SpeciesDexRecord {
fun addAspects(addedAspects: Set<String>) {
aspects.addAll(addedAspects)
pokedexManager.onSpeciesRecordUpdated(this)
}
/** Returns true if the given Pokémon contains new information. Internal because it's only to be called from [FormDexRecord.wouldBeDifferent]. */
@@ -44,6 +44,9 @@ import com.cobblemon.mod.common.api.riding.sound.RideSoundSettingsList
import com.cobblemon.mod.common.api.spawning.TimeRange
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.api.types.adapters.ElementalTypeAdapter
import com.cobblemon.mod.common.net.messages.client.data.FormEvolutionOverride
import com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionEntry
import com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionSyncPacket
import com.cobblemon.mod.common.net.messages.client.data.SpeciesRegistrySyncPacket
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.pokemon.Species
@@ -243,6 +246,18 @@ object PokemonSpecies : JsonDataRegistry<Species> {
override fun sync(player: ServerPlayer) {
SpeciesRegistrySyncPacket(species.toList()).sendToPlayer(player)
// Sent after the species themselves so every species is already registered by the time this is decoded.
val evolutionEntries = species.map { singleSpecies ->
val formOverrides = singleSpecies.forms.mapNotNull { form ->
if (form.ownEvolutions == null && form.ownPreEvolution == null) {
null
} else {
FormEvolutionOverride(form.name, form.ownEvolutions, form.ownPreEvolution)
}
}
SpeciesEvolutionEntry(singleSpecies.resourceIdentifier, singleSpecies.evolutions, singleSpecies.preEvolution, formOverrides)
}
SpeciesEvolutionSyncPacket(evolutionEntries).sendToPlayer(player)
}
/**
@@ -25,6 +25,8 @@ interface PreEvolution {
val form: FormData
fun resolveForm(extraAspects: Set<String> = emptySet()): FormData = form
companion object {
fun of(species: Species, form: FormData = species.standardForm): PreEvolution = StandardPreEvolution(species, form)
@@ -11,6 +11,8 @@ package com.cobblemon.mod.common.api.pokemon.requirement
import com.cobblemon.mod.common.api.pokemon.evolution.ContextEvolution
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.resources.ResourceLocation
import java.util.WeakHashMap
/**
* Represents a universal requirement suitable for various checks on pokemon..
@@ -32,4 +34,11 @@ fun interface Requirement {
*/
fun check(pokemon: Pokemon): Boolean
val pokedexIcon: ResourceLocation? get() = pokedexIconOverrides[this]
val pokedexTooltip: String? get() = pokedexTooltipOverrides[this]
companion object {
val pokedexIconOverrides = WeakHashMap<Requirement, ResourceLocation>()
val pokedexTooltipOverrides = WeakHashMap<Requirement, String>()
}
}
@@ -10,6 +10,8 @@ package com.cobblemon.mod.common.api.spawning
import com.cobblemon.mod.common.api.spawning.TimeRange.Companion.timeRanges
import com.cobblemon.mod.common.api.spawning.condition.SpawningCondition
import com.cobblemon.mod.common.util.lang
import net.minecraft.network.chat.MutableComponent
import com.cobblemon.mod.common.util.adapters.IntRangesAdapter
/**
@@ -49,4 +51,25 @@ class TimeRange : IntRanges {
constructor() : super()
constructor(vararg ranges: IntRange) : super(*ranges)
fun displayName(): MutableComponent? {
val key = timeRanges.entries.firstOrNull { entry -> this == entry.value }?.key ?: return null
return lang("ui.time_range.$key")
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TimeRange) return false
if (other.ranges.size != this.ranges.size) return false
other.ranges.forEachIndexed { index, otherRange ->
if (this.ranges[index] != otherRange) return false
}
return true
}
override fun hashCode(): Int {
return ranges.hashCode()
}
}
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.spawning.condition
import com.cobblemon.mod.common.util.lang
import net.minecraft.network.chat.MutableComponent
import net.minecraft.world.level.Level
/**
@@ -42,4 +44,7 @@ enum class MoonPhase {
fun ofWorld(world: Level): MoonPhase = VALUES[world.moonPhase]
}
fun displayName(): MutableComponent {
return lang("ui.moon_phase.${this.name.lowercase()}")
}
}
@@ -45,6 +45,7 @@ import com.cobblemon.mod.common.client.render.entity.PokeBobberEntityRenderer
import com.cobblemon.mod.common.client.render.generic.GenericBedrockRenderer
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.PlayerRecallBallRenderer
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
@@ -436,8 +437,10 @@ object CobblemonClient {
var renderer: LivingEntityRenderer<Player, PlayerModel<Player>>? =
skinMap?.get(PlayerSkin.Model.WIDE) as LivingEntityRenderer<Player, PlayerModel<Player>>
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
renderer = skinMap[PlayerSkin.Model.SLIM] as LivingEntityRenderer<Player, PlayerModel<Player>>?
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
}
private fun registerMenuScreens() {
@@ -32,6 +32,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.ActiveAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PrimaryAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer.Companion.ease
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
@@ -320,6 +321,7 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
ballOffset = 0f
ballRotOffset = 0f
sendOutPosition = null
currentEntity.ownerUUID?.let { RecallArmAnimationTracker.start(it, currentEntity.exposedBall) }
afterOnClient(seconds = BEAM_EXTEND_TIME) {
activeSendoutScale = 1F
@@ -36,32 +36,33 @@ import com.cobblemon.mod.common.client.gui.handleProfileDebugKeys
import com.cobblemon.mod.common.client.gui.logProfileTranslations
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.BASE_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HEADER_BAR_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.ICONS_ARROW_PADDING_AROUND
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.ICONS_PADDING_AROUND
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCALE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_ABILITIES
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_DESCRIPTION
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_DROPS
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_EVOLUTION_TREE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_ICON_SIZE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_MOVES
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_SIZE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.TAB_STATS
import com.cobblemon.mod.common.client.gui.pokedex.widgets.AbilitiesWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.DescriptionWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.DropsScrollingWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.EntriesScrollingWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.MovesLearnsetWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.PokemonInfoWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.SearchWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.SizeWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.StatsWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.*
import com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree.EvolutionTreeWidget
import com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree.debugEvolutionRequirementRendering
import com.cobblemon.mod.common.client.pokedex.PokedexType
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.abilities.HiddenAbility
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.isInventoryKeyPressed
import com.cobblemon.mod.common.util.lang
import com.mojang.blaze3d.platform.InputConstants
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.EditBox
@@ -94,6 +95,10 @@ class PokedexGUI private constructor(
private val categoryBarOverlay = cobblemonResource("textures/gui/pokedex/pokedex_screen_bar_category.png")
// TODO: separate into smaller components / widgets?
private val backgroundOverlay = cobblemonResource("textures/gui/pokedex/pokedex_screen_info_overlay.png")
private val expandedBackgroundOverlay = cobblemonResource("textures/gui/pokedex/pokedex_screen_info_overlay_expanded.png")
private val tabSelectArrow = cobblemonResource("textures/gui/pokedex/select_arrow.png")
private val tabIcons = arrayOf(
cobblemonResource("textures/gui/pokedex/tab_info.png"),
@@ -101,7 +106,8 @@ class PokedexGUI private constructor(
cobblemonResource("textures/gui/pokedex/tab_size.png"),
cobblemonResource("textures/gui/pokedex/tab_stats.png"),
cobblemonResource("textures/gui/pokedex/tab_drops.png"),
cobblemonResource("textures/gui/pokedex/tab_moves.png")
cobblemonResource("textures/gui/pokedex/tab_moves.png"),
cobblemonResource("textures/gui/pokedex/tab_evolution_tree.png"),
)
val arrowUpIcon = cobblemonResource("textures/gui/pokedex/arrow_up.png")
@@ -114,6 +120,8 @@ class PokedexGUI private constructor(
TAB_MOVES
)
private val ICONS_PADDING_BETWEEN = (BASE_WIDTH / 2 - ICONS_PADDING_AROUND * 2) / tabIcons.size
/**
* Attempts to open this screen for a client.
*/
@@ -132,6 +140,7 @@ class PokedexGUI private constructor(
var oldDragPosX = 0.0
var canDragRender = false
private var activeDragableElement: GuiEventListener? = null
private var filteredPokedex: Collection<PokedexDef> = mutableListOf()
private var seenCount = "0000"
@@ -155,13 +164,29 @@ class PokedexGUI private constructor(
private lateinit var scrollScreen: EntriesScrollingWidget
private lateinit var pokemonInfoWidget: PokemonInfoWidget
private lateinit var searchWidget: SearchWidget
private lateinit var pokemonNameWidget: PokemonNameWidget
private var selectedSearchByType: SearchByType = SearchByType.SPECIES
private var selectedCategoryFilter: PokedexCategoryFilterType = PokedexCategoryFilterType.ALL
private val tabButtons: MutableList<ScaledButton> = mutableListOf()
var seenShinyStates = setOf<String>()
var shiny = false
var maleRatio = -1F
var gender = Gender.GENDERLESS
var aspects = mutableSetOf<String>()
lateinit var tabInfoElement: GuiEventListener
var tabInfoIndex = TAB_DESCRIPTION
var evolutionTreeExpanded = false
set(value) {
field = value
if (::pokemonInfoWidget.isInitialized) {
pokemonInfoWidget.active = !value
pokemonInfoWidget.visible = !value
}
}
override fun renderBlurredBackground(delta: Float) {}
override fun renderMenuBackground(context: GuiGraphics) {}
@@ -180,7 +205,7 @@ class PokedexGUI private constructor(
//Info Widget
if (::pokemonInfoWidget.isInitialized) removeWidget(pokemonInfoWidget)
pokemonInfoWidget = PokemonInfoWidget(x + 180, y + 28) { newForm -> updateSelectedForm(newForm) }
pokemonInfoWidget = PokemonInfoWidget(this, x + 180, y + 28) { newForm -> updateSelectedForm(newForm) }
addRenderableWidget(pokemonInfoWidget)
setUpTabs()
@@ -192,6 +217,10 @@ class PokedexGUI private constructor(
searchWidget = SearchWidget(x + 26, y + 28, 120, HEADER_BAR_HEIGHT, update = ::updateFilters)
addRenderableWidget(searchWidget)
if (::pokemonNameWidget.isInitialized) removeWidget(pokemonNameWidget)
pokemonNameWidget = PokemonNameWidget(this, x + 180, y + 28)
addRenderableWidget(pokemonNameWidget)
if (::regionSelectWidgetUp.isInitialized) removeWidget(regionSelectWidgetUp)
regionSelectWidgetUp = ScaledButton(
buttonX = (x + 95).toFloat(),
@@ -367,6 +396,14 @@ class PokedexGUI private constructor(
shadow = true
)
blitk(
matrixStack = matrices,
texture = if (evolutionTreeExpanded) expandedBackgroundOverlay else backgroundOverlay,
x = pokemonInfoWidget.x, y = pokemonInfoWidget.y,
width = HALF_OVERLAY_WIDTH,
height = HALF_OVERLAY_HEIGHT
)
// Category filter
blitk(
matrixStack = matrices,
@@ -402,7 +439,7 @@ class PokedexGUI private constructor(
blitk(
matrixStack = matrices,
texture = tabSelectArrow,
x = (x + 191.5F + (22F * tabInfoIndex)) / SCALE,
x = (x + BASE_WIDTH / 2 + ICONS_ARROW_PADDING_AROUND + tabInfoIndex * ICONS_PADDING_BETWEEN) / SCALE,
y = (y + 177) / SCALE,
width = 12,
height = 6,
@@ -441,6 +478,7 @@ class PokedexGUI private constructor(
val canDisplayEntry = true //selectedForm?.unlockForms
if (::pokemonInfoWidget.isInitialized
&& pokemonInfoWidget.active
&& !pokemonInfoWidget.suppressViewport
&& pokemonInfoWidget.isWithinPortraitSpace(mouseX, mouseY)
&& canDisplayEntry == true
@@ -449,6 +487,12 @@ class PokedexGUI private constructor(
isDragging = true
oldDragPosX = mouseX
playSound(CobblemonSounds.POKEDEX_CLICK_SHORT)
activeDragableElement = pokemonInfoWidget
} else if (tabInfoIndex == TAB_EVOLUTION_TREE &&
::tabInfoElement.isInitialized &&
(tabInfoElement as EvolutionTreeWidget).isHovered(mouseX, mouseY)
) {
activeDragableElement = tabInfoElement
}
return try {
super.mouseClicked(mouseX, mouseY, button)
@@ -460,14 +504,18 @@ class PokedexGUI private constructor(
override fun mouseReleased(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
if (canDragRender) canDragRender = false
if (isDragging) isDragging = false
activeDragableElement = null
return super.mouseReleased(pMouseX, pMouseY, pButton)
}
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
if (isDragging && canDragRender) {
if (isDragging && canDragRender && activeDragableElement == pokemonInfoWidget) {
val dragOffsetY = (oldDragPosX - mouseX).toFloat()
pokemonInfoWidget.rotationY = (((pokemonInfoWidget.rotationY + dragOffsetY) % 360 + 360) % 360)
} else if (activeDragableElement == tabInfoElement) {
tabInfoElement.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
oldDragPosX = mouseX
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
@@ -558,6 +606,8 @@ class PokedexGUI private constructor(
selectedForm = CobblemonClient.clientPokedexData.getEncounteredForms(newSelectedEntry).firstOrNull()
pokemonInfoWidget.setDexEntry(selectedEntry!!)
pokemonNameWidget.update(selectedEntry!!)
displaytabInfoElement(tabInfoIndex)
}
@@ -569,7 +619,7 @@ class PokedexGUI private constructor(
for (i in tabIcons.indices) {
tabButtons.add(ScaledButton(
x + 190.5F + (i * 22F),
x + BASE_WIDTH / 2 + ICONS_PADDING_AROUND + i * ICONS_PADDING_BETWEEN,
y + 181.5F,
TAB_ICON_SIZE,
TAB_ICON_SIZE,
@@ -582,6 +632,8 @@ class PokedexGUI private constructor(
}
fun displaytabInfoElement(tabIndex: Int, update: Boolean = true) {
if (tabIndex != TAB_EVOLUTION_TREE) evolutionTreeExpanded = false
val showActiveTab = selectedEntry?.let { selectedForm in getSufficientlyKnownForms(it, tabIndex) } == true
var statSubIndex = 0
@@ -633,6 +685,9 @@ class PokedexGUI private constructor(
TAB_MOVES -> {
tabInfoElement = MovesLearnsetWidget(x + 180, y + 28)
}
TAB_EVOLUTION_TREE -> {
tabInfoElement = EvolutionTreeWidget(this, x, y)
}
}
val element = tabInfoElement
if (element is Renderable && element is NarratableEntry) {
@@ -707,6 +762,9 @@ class PokedexGUI private constructor(
selectedForm = fallbackForm
) { next -> cycleSelectedForm(next) }
}
TAB_EVOLUTION_TREE -> {
(tabInfoElement as EvolutionTreeWidget).setup(selectedEntry, selectedForm)
}
}
} else {
if (tabInfoIndex != TAB_DESCRIPTION) displaytabInfoElement(TAB_DESCRIPTION)
@@ -770,6 +828,10 @@ class PokedexGUI private constructor(
}
}
if (tabInfoIndex == TAB_EVOLUTION_TREE && keyCode == InputConstants.KEY_SEMICOLON) {
debugEvolutionRequirementRendering()
}
return super.keyPressed(keyCode, scanCode, modifiers)
}
@@ -16,6 +16,8 @@ object PokedexGUIConstants {
const val HEADER_BAR_HEIGHT = 11
const val POKEMON_DESCRIPTION_HEIGHT = 42
const val POKEMON_DESCRIPTION_PADDING = 9
const val ICONS_PADDING_AROUND = 18.5f
const val ICONS_ARROW_PADDING_AROUND = ICONS_PADDING_AROUND + 1
const val TAB_ICON_SIZE = 16
@@ -36,6 +38,7 @@ object PokedexGUIConstants {
const val TAB_STATS = 3
const val TAB_DROPS = 4
const val TAB_MOVES = 5
const val TAB_EVOLUTION_TREE = 6
// RowScrollingWidget
const val SCROLL_BASE_HEIGHT = 141
@@ -13,38 +13,101 @@ import com.cobblemon.mod.common.api.text.font
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
private val tooltipEdge = cobblemonResource("textures/gui/pokedex/tooltip_edge.png")
private val tooltipBackground = cobblemonResource("textures/gui/pokedex/tooltip_background.png")
fun renderTooltip(context: GuiGraphics, text: MutableComponent, posX: Int, posY: Int, delta: Float, offsetY: Int = 0) {
private const val TOOLTIP_SLICE_SIZE = 11
fun renderTooltip(
context: GuiGraphics,
text: MutableComponent,
posX: Int,
posY: Int,
delta: Float,
offsetY: Int = 0,
) {
renderTooltip(
context,
listOf(text),
posX,
posY,
delta,
offsetY,
)
}
fun renderTooltip(
context: GuiGraphics,
text: List<MutableComponent>,
posX: Int,
posY: Int,
delta: Float,
offsetY: Int = 0,
) {
val poseStack = context.pose()
val textWidth = Minecraft.getInstance().font.width(text.font(CobblemonResources.DEFAULT_LARGE))
val tooltipWidth = textWidth + 6
val tooltipHeight = 11
val textWidth = text.maxOf { Minecraft.getInstance().font.width(it.font(CobblemonResources.DEFAULT_LARGE)) }
val tooltipPadding = 6
val tooltipWidth = textWidth + tooltipPadding
val tooltipTop = posY + offsetY
poseStack.pushPose()
poseStack.translate(0.0, 0.0, 1000.0)
Minecraft.getInstance().let {
it.mainRenderTarget.bindWrite(false)
context.enableScissor(
posX - (tooltipWidth / 2),
tooltipTop + 1,
(posX - (tooltipWidth / 2)) + tooltipWidth,
tooltipTop + 10
tooltipTop + TOOLTIP_SLICE_SIZE * text.size - 1
)
it.gameRenderer.processBlurEffect(delta)
context.disableScissor()
it.mainRenderTarget.bindWrite(true)
}
blitk(matrixStack = poseStack, texture = tooltipEdge, x = posX - (tooltipWidth / 2) - 1, y = tooltipTop, width = 1, height = tooltipHeight)
blitk(matrixStack = poseStack, texture = tooltipBackground, x = posX - (tooltipWidth / 2), y = tooltipTop, width = tooltipWidth, height = tooltipHeight)
blitk(matrixStack = poseStack, texture = tooltipEdge, x = posX + (tooltipWidth / 2), y = tooltipTop, width = 1, height = tooltipHeight)
drawScaledText(context = context, font = CobblemonResources.DEFAULT_LARGE, text = text, x = posX, y = tooltipTop + 1, shadow = true, centered = true)
val totalHeight = TOOLTIP_SLICE_SIZE * text.size
blitSlicedVertical(poseStack, tooltipEdge, posX - (tooltipWidth / 2) - 1, tooltipTop, 1, totalHeight)
blitSlicedVertical(poseStack, tooltipBackground, posX - (tooltipWidth / 2), tooltipTop, tooltipWidth, totalHeight)
blitSlicedVertical(poseStack, tooltipEdge, posX + (tooltipWidth / 2), tooltipTop, 1, totalHeight)
val centered = text.size == 1
text.forEachIndexed { index, it ->
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = it,
x = if (centered) posX else posX - tooltipWidth / 2 + tooltipPadding / 2,
y = tooltipTop + 1 + TOOLTIP_SLICE_SIZE * index,
shadow = true,
centered = centered
)
}
poseStack.popPose()
}
// Stretching the whole 11px image over an arbitrary height thickens the caps as more lines are added, so
// instead the caps are drawn 1:1 and only the flat fill row is stretched to cover the remaining height
private fun blitSlicedVertical(
poseStack: PoseStack,
texture: ResourceLocation,
x: Number,
y: Int,
width: Number,
totalHeight: Int,
) {
val middleHeight = totalHeight - 2
blitk(matrixStack = poseStack, texture = texture, x = x, y = y, width = width, height = 1, vOffset = 0, textureHeight = TOOLTIP_SLICE_SIZE)
blitk(matrixStack = poseStack, texture = texture, x = x, y = y + 1, width = width, height = middleHeight, vOffset = middleHeight, textureHeight = TOOLTIP_SLICE_SIZE * middleHeight)
blitk(matrixStack = poseStack, texture = texture, x = x, y = y + 1 + middleHeight, width = width, height = 1, vOffset = TOOLTIP_SLICE_SIZE - 1, textureHeight = TOOLTIP_SLICE_SIZE)
}
@@ -20,8 +20,8 @@ import net.minecraft.client.sounds.SoundManager
import net.minecraft.resources.ResourceLocation
class ScaledButton(
var buttonX: Float,
var buttonY: Float,
buttonX: Float,
buttonY: Float,
val buttonWidth: Number,
val buttonHeight: Number,
var resource: ResourceLocation? = null,
@@ -30,6 +30,18 @@ class ScaledButton(
val clickAction: Button.OnPress
): Button(buttonX.toInt(), buttonY.toInt(), buttonWidth.toInt(), buttonHeight.toInt(), "".text(), clickAction, DEFAULT_NARRATION), CobblemonRenderable {
var buttonX: Float = buttonX
set(value) {
field = value
this.x = value.toInt()
}
var buttonY: Float = buttonY
set(value) {
field = value
this.y = value.toInt()
}
var isWidgetActive = false
var isVisible = true
@@ -12,14 +12,13 @@ import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.gui.ScrollingWidget
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCALE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_BAR_WIDTH
@@ -27,19 +26,14 @@ import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_BA
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_SLOT_SIZE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_SLOT_SPACING
import com.cobblemon.mod.common.client.gui.pokedex.widgets.EntriesScrollingWidget.PokemonScrollSlotRow
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.RenderablePokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.network.chat.Component
import net.minecraft.util.Mth
import org.joml.Quaternionf
import org.joml.Vector3f
class EntriesScrollingWidget(val pX: Int, val pY: Int, val setPokedexEntry: (PokedexEntry) -> (Unit)): ScrollingWidget<PokemonScrollSlotRow>(
width = PokedexGUIConstants.HALF_OVERLAY_WIDTH,
@@ -135,13 +129,6 @@ class EntriesScrollingWidget(val pX: Int, val pY: Int, val setPokedexEntry: (Pok
val discoveryLevelList: MutableList<PokedexEntryProgress>,
val setPokedexEntry : (PokedexEntry) -> (Unit)
): Slot<PokemonScrollSlotRow>() {
companion object {
private val slotResource = cobblemonResource("textures/gui/pokedex/pokedex_slot.png")
private val slotHighlight = cobblemonResource("textures/gui/pokedex/slot_select.png")
private val caughtIcon = cobblemonResource("textures/gui/pokedex/caught_icon_small.png")
private val unknownIcon = cobblemonResource("textures/gui/pokedex/pokedex_slot_unknown.png")
private val unimplementedIcon = cobblemonResource("textures/gui/pokedex/pokedex_slot_unimplemented.png")
}
val runtime = MoLangRuntime().setupClient().setup().also {
it.environment.query.addFunction("get_pokedex") { CobblemonClient.clientPokedexData.struct }
}
@@ -161,128 +148,42 @@ class EntriesScrollingWidget(val pX: Int, val pY: Int, val setPokedexEntry: (Pok
hovered: Boolean,
tickDelta: Float
) {
dexDataList.forEachIndexed { index, dexData ->
val state = FloatingState()
val species = PokemonSpecies.getByIdentifier(dexData.speciesId)
//FIXME: This may not work properly when accounting for custom pokemon with the same dex number
val pokemonNumber = (species?.nationalPokedexNumber?.toString() ?: "0").padStart(4, '0')
val speciesNumber = pokemonNumber.text()
dexDataList.forEachIndexed { index, pokedexEntry ->
val species = PokemonSpecies.getByIdentifier(pokedexEntry.speciesId)
val discoveryLevel = discoveryLevelList[index]
val firstVisibleForm = CobblemonClient.clientPokedexData.getEncounteredForms(dexData).firstOrNull()
val shouldDrawMon = firstVisibleForm != null
val firstVisibleForm = CobblemonClient.clientPokedexData.getEncounteredForms(pokedexEntry).firstOrNull()
if (species == null) {
return@forEachIndexed
}
val matrices = context.pose()
val renderablePokemon =
if (firstVisibleForm != null) {
val firstVisibleGender = CobblemonClient.clientPokedexData.getSeenGenders(pokedexEntry, firstVisibleForm).firstOrNull()
val shinyStates = CobblemonClient.clientPokedexData.getSeenShinyStates(pokedexEntry, firstVisibleForm)
val firstVisibleShiny = shinyStates.count() == 1 && shinyStates.first() == "shiny"
val formAspects = species.forms.firstOrNull { it.name.equals(firstVisibleForm.displayForm, ignoreCase = true) }?.aspects ?: species.standardForm.aspects
val seenAspects = CobblemonClient.clientPokedexData.getSeenAspects(pokedexEntry)
val variationAspects = pokedexEntry.variations.mapNotNull { it.aspects.firstOrNull { it in seenAspects } }
val aspectsToDraw = (pokedexEntry.displayAspects + variationAspects + formAspects + (firstVisibleGender ?: Gender.GENDERLESS).name.lowercase()).toMutableSet()
if (firstVisibleShiny) {
aspectsToDraw.add("shiny")
}
val startPosX = x + ((SCROLL_SLOT_SPACING + SCROLL_SLOT_SIZE) * index)
val startPosY = y + SCROLL_SLOT_SPACING + 1
blitk(
matrixStack = matrices,
texture = slotResource,
x = startPosX,
y = startPosY,
width = SCROLL_SLOT_SIZE,
height = SCROLL_SLOT_SIZE
)
if (getHoveredSlotIndex(mouseX, mouseY) == index) {
blitk(
matrixStack = matrices,
texture = slotHighlight,
x = startPosX,
y = startPosY,
width = SCROLL_SLOT_SIZE,
height = SCROLL_SLOT_SIZE,
vOffset = SCROLL_SLOT_SIZE,
textureHeight = SCROLL_SLOT_SIZE * 2
)
}
if (shouldDrawMon) {
val firstVisibleGender = CobblemonClient.clientPokedexData.getSeenGenders(dexData, firstVisibleForm).firstOrNull()
val shinyStates = CobblemonClient.clientPokedexData.getSeenShinyStates(dexData, firstVisibleForm)
val firstVisibleShiny = shinyStates.count() == 1 && shinyStates.first() == "shiny"
val formAspects = species.forms.firstOrNull { it.name.equals(firstVisibleForm.displayForm, ignoreCase = true) }?.aspects ?: species.standardForm.aspects
val seenAspects = CobblemonClient.clientPokedexData.getSeenAspects(dexData)
val variationAspects = dexData.variations.mapNotNull { it.aspects.firstOrNull { it in seenAspects } }
context.enableScissor(
startPosX + 1,
startPosY + 1,
startPosX + SCROLL_SLOT_SIZE - 1,
startPosY + SCROLL_SLOT_SIZE - 2
)
val aspectsToDraw = (dexData.displayAspects + variationAspects + formAspects + (firstVisibleGender ?: Gender.GENDERLESS).name.lowercase()).toMutableSet()
if (firstVisibleShiny) {
aspectsToDraw.add("shiny")
RenderablePokemon(species, aspectsToDraw)
} else {
null
}
state.currentAspects = aspectsToDraw
matrices.pushPose()
matrices.translate(startPosX + (SCROLL_SLOT_SIZE / 2.0), startPosY + 1.0, 0.0)
matrices.scale(2.5F, 2.5F, 1F)
drawProfilePokemon(
renderablePokemon = RenderablePokemon(species, aspectsToDraw),
matrixStack = matrices,
rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(13F, 35F, 0F)),
state = state,
partialTicks = 0F,
scale = 4.5F
)
matrices.popPose()
context.disableScissor()
} else {
blitk(
matrixStack = matrices,
texture = unknownIcon,
x = startPosX + 8.5,
y = startPosY + 9,
width = 8,
height = 10
)
if (!species.implemented) {
blitk(
matrixStack = matrices,
texture = unimplementedIcon,
x = (startPosX + 14) / SCALE,
y = (startPosY + 15.5) / SCALE,
width = 7,
height = 7,
scale = SCALE
)
}
}
// Ensure elements are not hidden behind Pokémon render
matrices.pushPose()
matrices.translate(0.0, 0.0, 100.0)
drawScaledText(
context = context,
text = speciesNumber,
x = startPosX + 1.5,//2,
y = startPosY + 2.5,//2
shadow = true,
scale = SCALE
PokemonSlotWidget.render(
context,
x = x + (SCROLL_SLOT_SPACING + SCROLL_SLOT_SIZE) * index,
y = y + SCROLL_SLOT_SPACING + 1,
getHoveredSlotIndex(mouseX, mouseY) == index,
species,
renderablePokemon,
discoveryLevel,
)
if (discoveryLevel == PokedexEntryProgress.OWNED) {
blitk(
matrixStack = matrices,
texture = caughtIcon,
x = (startPosX + 18) / SCALE,
y = (startPosY + 1.5) / SCALE,
width = 11,
height = 11,
scale = SCALE
)
}
matrices.popPose()
}
}
@@ -10,10 +10,10 @@ package com.cobblemon.mod.common.client.gui.pokedex.widgets
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.entry.PokedexCosmeticVariation
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.text.bold
@@ -25,8 +25,9 @@ import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.ProfileTransformType
import com.cobblemon.mod.common.client.gui.TypeIcon
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUI
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_PORTRAIT_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_PORTRAIT_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.PORTRAIT_POKE_BALL_HEIGHT
@@ -52,15 +53,13 @@ import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.sounds.SoundEvent
import org.joml.Quaternionf
import org.joml.Vector3f
import java.io.FileNotFoundException
class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm) -> (Unit)) : SoundlessWidget(
class PokemonInfoWidget(val parent: PokedexGUI, val pX: Int, val pY: Int, val updateForm: (PokedexForm) -> (Unit)) : SoundlessWidget(
pX,
pY,
POKEMON_PORTRAIT_WIDTH,
@@ -82,7 +81,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
private val arrowFormLeft = cobblemonResource("textures/gui/pokedex/forms_arrow_left.png")
private val arrowFormRight = cobblemonResource("textures/gui/pokedex/forms_arrow_right.png")
private val caughtIcon = cobblemonResource("textures/gui/pokedex/caught_icon.png")
private val typeBar = cobblemonResource("textures/gui/pokedex/type_bar.png")
private val typeBarDouble = cobblemonResource("textures/gui/pokedex/type_bar_double.png")
@@ -100,9 +98,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
var currentEntry : PokedexEntry? = null
var speciesName: MutableComponent = Component.translatable("")
var speciesNumber: MutableComponent = "0000".text()
val runtime = MoLangRuntime().setupClient().setup().also {
it.environment.query.addFunction("get_pokedex") { CobblemonClient.clientPokedexData.struct }
}
@@ -111,10 +106,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
var selectedFormIndex: Int = 0
var type: Array<ElementalType?> = arrayOf(null, null)
var seenShinyStates: Set<String> = setOf()
var shiny = false
var maleRatio = -1F
var gender: Gender = Gender.GENDERLESS
var renderablePokemon : RenderablePokemon? = null
@@ -195,7 +186,10 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
20,
resource = buttonGenderMale,
clickAction = {
if (maleRatio > 0 && maleRatio < 1) gender = if (gender == Gender.MALE) Gender.FEMALE else Gender.MALE
val maleRatio = parent.maleRatio
if (maleRatio > 0 && maleRatio < 1) {
parent.gender = if (parent.gender == Gender.MALE) Gender.FEMALE else Gender.MALE
}
updateAspects()
}
).apply { addWidget(this) }
@@ -207,8 +201,8 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
20,
buttonNone,
clickAction = {
if (seenShinyStates.size > 1) {
shiny = !shiny
if (parent.seenShinyStates.size > 1) {
parent.shiny = !parent.shiny
updateAspects()
}
}
@@ -263,8 +257,7 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
val currentEntry = this.currentEntry ?: return
val hasKnowledge =
CobblemonClient.clientPokedexData.getKnowledgeForSpecies(currentEntry.speciesId) != PokedexEntryProgress.UNREGISTERED
val hasKnowledge = CobblemonClient.clientPokedexData.getKnowledgeForSpecies(currentEntry.speciesId) != PokedexEntryProgress.UNREGISTERED
val species = currentEntry.speciesId.let { PokemonSpecies.getByIdentifier(it) } ?: return
val matrices = context.pose()
@@ -277,37 +270,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
height = HALF_OVERLAY_HEIGHT
)
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = speciesNumber.bold(),
x = pX + 3,
y = pY + 1,
shadow = true
)
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = (if (hasKnowledge) speciesName else lang("ui.generic.question_marks")).bold(),
x = pX + 26,
y = pY + 1,
colour = 0x606B6E
)
// Caught icon
if (isSelectedPokemonOwned()) {
blitk(
matrixStack = matrices,
texture = caughtIcon,
x = (pX + 129) / SCALE,
y = (pY + 2) / SCALE,
width = 14,
height = 14,
scale = SCALE
)
}
if (!suppressViewport) {
blitk(
matrixStack = matrices,
@@ -571,8 +533,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
if (species != null) {
this.visibleForms = CobblemonClient.clientPokedexData.getEncounteredForms(pokedexEntry).toMutableList()
this.speciesNumber = species.nationalPokedexNumber.toString().padStart(4, '0').text()
this.speciesName = species.translatedName
if (forms.isNotEmpty()) {
formLeftButton.active = true
@@ -598,23 +558,23 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
variationButtons.forEach { removeWidget(it.getWidget()) }
variationButtons.clear()
seenShinyStates = CobblemonClient.clientPokedexData.getSeenShinyStates(pokedexEntry, pokedexForm)
shiny = seenShinyStates.count() == 1 && seenShinyStates.first() == "shiny"
shinyButton.resource = if (shiny) buttonShiny else buttonNone
shinyButton.visible = shiny || seenShinyStates.size > 1
shinyButton.active = seenShinyStates.size > 1
parent.seenShinyStates = CobblemonClient.clientPokedexData.getSeenShinyStates(pokedexEntry, pokedexForm)
parent.shiny = parent.seenShinyStates.count() == 1 && parent.seenShinyStates.first() == "shiny"
shinyButton.resource = if (parent.shiny) buttonShiny else buttonNone
shinyButton.visible = parent.shiny || parent.seenShinyStates.size > 1
shinyButton.active = parent.seenShinyStates.size > 1
val form = species.forms.find { it.name.equals(pokedexForm.displayForm, ignoreCase = true) } ?: species.standardForm
maleRatio = form.maleRatio
parent.maleRatio = form.maleRatio
val seenGenders = CobblemonClient.clientPokedexData.getSeenGenders(pokedexEntry, pokedexForm)
val visibleGenders = seenGenders.filter { it != Gender.GENDERLESS }
if (visibleGenders.isEmpty()) {
gender = Gender.GENDERLESS
parent.gender = Gender.GENDERLESS
genderButton.visible = false
genderButton.active = false
} else {
gender = visibleGenders.first()
parent.gender = visibleGenders.first()
genderButton.visible = true
genderButton.active = visibleGenders.size > 1
}
@@ -693,8 +653,8 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
return
}
genderButton.resource = if (gender == Gender.FEMALE) buttonGenderFemale else buttonGenderMale
shinyButton.resource = if (shiny) buttonShiny else buttonNone
genderButton.resource = if (parent.gender == Gender.FEMALE) buttonGenderFemale else buttonGenderMale
shinyButton.resource = if (parent.shiny) buttonShiny else buttonNone
val species = currentEntry?.speciesId?.let { PokemonSpecies.getByIdentifier(it) }
if (species != null) {
@@ -703,12 +663,14 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
updateType(species, form)
val aspects = mutableSetOf<String>()
if (shiny) aspects.add(SHINY_ASPECT.aspect)
val aspects = parent.aspects
aspects.clear()
if (gender == Gender.FEMALE) {
if (parent.shiny) aspects.add(SHINY_ASPECT.aspect)
if (parent.gender == Gender.FEMALE) {
aspects.add("female")
} else if (gender == Gender.MALE) {
} else if (parent.gender == Gender.MALE) {
aspects.add("male")
}
@@ -0,0 +1,100 @@
/*
* 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.gui.pokedex.widgets
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.text.bold
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUI
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_PORTRAIT_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_PORTRAIT_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCALE
import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
class PokemonNameWidget(
val parent: PokedexGUI,
val pX: Int,
val pY: Int,
) : SoundlessWidget(
pX,
pY,
POKEMON_PORTRAIT_WIDTH,
POKEMON_PORTRAIT_HEIGHT,
lang("ui.pokedex.pokemon_name"),
) {
companion object {
private val caughtIcon = cobblemonResource("textures/gui/pokedex/caught_icon.png")
}
var hasKnowledge: Boolean = false
var isOwned: Boolean = false
var speciesName: MutableComponent = Component.translatable("")
var speciesNumber: MutableComponent = "0000".text()
override fun renderWidget(
context: GuiGraphics,
mouseX: Int,
mouseY: Int,
partialTick: Float
) {
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = speciesNumber.bold(),
x = pX + 3,
y = pY + 1,
shadow = true
)
if (hasKnowledge) {
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = speciesName.bold(),
x = pX + 26,
y = pY + 1,
colour = 0x606B6E
)
}
if (isOwned) {
blitk(
matrixStack = context.pose(),
texture = caughtIcon,
x = (pX + 129) / SCALE,
y = (pY + 2) / SCALE,
width = 14,
height = 14,
scale = SCALE
)
}
}
fun update(pokedexEntry: PokedexEntry) {
val species = PokemonSpecies.getByIdentifier(pokedexEntry.speciesId) ?: return
val progress = CobblemonClient.clientPokedexData.getKnowledgeForSpecies(pokedexEntry.speciesId)
this.hasKnowledge = progress != PokedexEntryProgress.UNREGISTERED
this.isOwned = progress == PokedexEntryProgress.OWNED
this.speciesNumber = species.nationalPokedexNumber.toString().padStart(4, '0').text()
this.speciesName = species.translatedName
}
}
@@ -0,0 +1,151 @@
/*
* 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.gui.pokedex.widgets
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCALE
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_SLOT_SIZE
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
import com.cobblemon.mod.common.pokemon.RenderablePokemon
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import net.minecraft.client.gui.GuiGraphics
import org.joml.Quaternionf
import org.joml.Vector3f
abstract class PokemonSlotWidget {
companion object {
private val slotResource = cobblemonResource("textures/gui/pokedex/pokedex_slot.png")
private val slotHighlight = cobblemonResource("textures/gui/pokedex/slot_select.png")
private val caughtIcon = cobblemonResource("textures/gui/pokedex/caught_icon_small.png")
private val unknownIcon = cobblemonResource("textures/gui/pokedex/pokedex_slot_unknown.png")
private val unimplementedIcon = cobblemonResource("textures/gui/pokedex/pokedex_slot_unimplemented.png")
fun render(
context: GuiGraphics,
x: Int,
y: Int,
isHovered: Boolean,
species: Species,
renderablePokemon: RenderablePokemon?,
discoveryLevel: PokedexEntryProgress,
) {
val shouldDrawMon = renderablePokemon != null
// FIXME: This may not work properly when accounting for custom pokemon with the same dex number
val pokemonNumber = species.nationalPokedexNumber.toString().padStart(4, '0')
val speciesNumber = pokemonNumber.text()
val matrices = context.pose()
blitk(
matrixStack = matrices,
texture = slotResource,
x = x,
y = y,
width = SCROLL_SLOT_SIZE,
height = SCROLL_SLOT_SIZE,
)
if (isHovered) {
blitk(
matrixStack = matrices,
texture = slotHighlight,
x = x,
y = y,
width = SCROLL_SLOT_SIZE,
height = SCROLL_SLOT_SIZE,
vOffset = SCROLL_SLOT_SIZE,
textureHeight = SCROLL_SLOT_SIZE * 2,
)
}
if (shouldDrawMon && discoveryLevel != PokedexEntryProgress.UNREGISTERED) {
context.enableScissor(
x + 1,
y + 1,
x + SCROLL_SLOT_SIZE - 1,
y + SCROLL_SLOT_SIZE - 2,
)
matrices.pushPose()
matrices.translate(x + SCROLL_SLOT_SIZE / 2.0, y + 1.0, 0.0)
matrices.scale(2.5F, 2.5F, 1F)
val state = FloatingState()
state.currentAspects = renderablePokemon.aspects
drawProfilePokemon(
renderablePokemon = renderablePokemon,
matrixStack = matrices,
rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(13F, 35F, 0F)),
state = state,
partialTicks = 0F,
scale = 4.5F
)
matrices.popPose()
context.disableScissor()
} else {
blitk(
matrixStack = matrices,
texture = unknownIcon,
x = x + 8.5,
y = y + 9,
width = 8,
height = 10
)
if (!species.implemented) {
blitk(
matrixStack = matrices,
texture = unimplementedIcon,
x = (x + 14) / SCALE,
y = (y + 15.5) / SCALE,
width = 7,
height = 7,
scale = SCALE
)
}
}
// Ensure elements are not hidden behind Pokémon render
matrices.pushPose()
matrices.translate(0.0, 0.0, 100.0)
drawScaledText(
context = context,
text = speciesNumber,
x = x + 1.5,
y = y + 2.5,
shadow = true,
scale = SCALE
)
if (discoveryLevel == PokedexEntryProgress.OWNED) {
blitk(
matrixStack = matrices,
texture = caughtIcon,
x = (x + 18) / SCALE,
y = (y + 1.5) / SCALE,
width = 11,
height = 11,
scale = SCALE
)
}
matrices.popPose()
}
}
}
@@ -0,0 +1,143 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.gui.pokedex.widgets.evolutiontree
import com.cobblemon.mod.common.api.pokemon.Natures
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeature
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeatureProvider
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
import com.cobblemon.mod.common.api.pokemon.feature.StringSpeciesFeature
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
import com.cobblemon.mod.common.api.text.add
import com.cobblemon.mod.common.api.text.green
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.asTranslated
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.locale.Language
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.world.item.Items
internal fun describePokemonProperties(properties: PokemonProperties): MutableComponent? {
if (hasUndescribedProperty(properties)) {
return null
}
val descriptors = mutableListOf<MutableComponent>()
properties.species?.let { PokemonSpecies.getByIdentifier(cobblemonResource(it)) }?.let {
descriptors.add(it.translatedName.plainCopy().green())
}
properties.gender?.let {
descriptors.add(lang("gender.${it.name.lowercase()}").green())
}
properties.nickname?.let {
descriptors.add(lang("ui.pokedex.requirement.properties.nickname", it.plainCopy().green()))
}
properties.type?.let {
val typeName = ElementalTypes.get(it)?.displayName?.plainCopy() ?: Component.literal(it)
descriptors.add(lang("ui.pokedex.requirement.properties.type", typeName.green()))
}
properties.nature?.let {
val natureName = Natures.getNature(it.asIdentifierDefaultingNamespace())?.displayName?.asTranslated() ?: Component.literal(it)
descriptors.add(lang("ui.pokedex.requirement.properties.nature", natureName.green()))
}
properties.customProperties.forEach { customProperty ->
describeCustomProperty(customProperty)?.let { descriptors.add(it) }
}
val heldItemDescriptor = properties.heldItem?.let { heldItem ->
val itemId = heldItem.substringBefore('[').trim().asIdentifierDefaultingNamespace()
val item = BuiltInRegistries.ITEM.get(itemId)
if (item == Items.AIR) null else lang("ui.pokedex.requirement.properties.held_item", item.description.plainCopy().green())
}
if (descriptors.isEmpty() && heldItemDescriptor == null) {
return null
}
val mainDescriptor = when {
descriptors.isEmpty() -> null
descriptors.size == 1 -> descriptors[0]
else -> {
val allButLast = descriptors.dropLast(1).reduce { acc, next -> acc.add(", ").add(next) }
lang("ui.pokedex.requirement.properties.and", allButLast, descriptors.last())
}
}
return when {
mainDescriptor != null && heldItemDescriptor != null -> mainDescriptor.add(" ").add(heldItemDescriptor)
mainDescriptor != null -> mainDescriptor
else -> heldItemDescriptor
}
}
private fun hasUndescribedProperty(properties: PokemonProperties): Boolean {
return properties.form != null ||
properties.shiny != null ||
properties.level != null ||
properties.friendship != null ||
properties.fullness != null ||
properties.pokeball != null ||
properties.ability != null ||
properties.status != null ||
properties.teraType != null ||
properties.dmaxLevel != null ||
properties.gmaxFactor != null ||
properties.tradeable != null ||
properties.originalTrainerType != null ||
properties.originalTrainer != null ||
properties.moves != null ||
properties.movesetBuilders != null ||
properties.cosmeticItem != null ||
properties.scaleModifier != null ||
properties.isAlpha != null ||
properties.minPerfectIVs != null ||
properties.customProperties.any { describeCustomProperty(it) == null }
}
private fun describeCustomProperty(property: CustomPokemonProperty): MutableComponent? {
return when (property) {
is IntSpeciesFeature -> describeIntSpeciesFeature(property)
is StringSpeciesFeature -> describeStringSpeciesFeature(property)
else -> null
}
}
private fun describeIntSpeciesFeature(property: IntSpeciesFeature): MutableComponent? {
val value = Component.literal(property.value.toString())
val overrideKey = "ui.pokedex.requirement.properties.custom.${property.name}"
if (Language.getInstance().has("cobblemon.$overrideKey")) {
return lang(overrideKey, value.green())
}
val displayName = (SpeciesFeatures.getFeature(property.name) as? IntSpeciesFeatureProvider)
?.display?.name?.takeIf { it.isNotBlank() }
?: return null
return lang("ui.pokedex.requirement.properties.int_feature", value.green(), displayName.asTranslated().green())
}
private fun describeStringSpeciesFeature(property: StringSpeciesFeature): MutableComponent? {
val key = "ui.pokedex.requirement.properties.custom.${property.name}"
if (!Language.getInstance().has("cobblemon.$key")) {
return null
}
val value = PokemonSpecies.getByIdentifier(cobblemonResource(property.value))?.translatedName?.plainCopy()
?: Component.literal(property.value)
return lang(key, value.green())
}
@@ -0,0 +1,48 @@
/*
* 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.gui.pokedex.widgets.evolutiontree
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import net.minecraft.client.Minecraft
import net.minecraft.network.chat.Component
fun debugEvolutionRequirementRendering() {
if (!Cobblemon.config.enableDebugKeys) {
return
}
val gaps = mutableListOf<Pair<String, String>>()
for (species in PokemonSpecies.implemented) {
val evolutions = species.evolutions + species.forms.flatMap { it.evolutions }
for (evolution in evolutions) {
if (renderEvolutionData(evolution) == null) {
gaps.add("Evolution: ${evolution::class.simpleName}" to species.showdownId())
}
for (requirement in evolution.requirements) {
if (resolveRequirementData(requirement) == null) {
gaps.add("Requirement: ${requirement::class.simpleName}" to species.showdownId())
}
}
}
}
val player = Minecraft.getInstance().player
if (gaps.isEmpty()) {
player?.sendSystemMessage(Component.literal("Evolution render debug: no gaps found."))
return
}
val byType = gaps.groupBy({ it.first }, { it.second })
println("Evolution render debug found ${gaps.size} gap(s) across ${byType.size} type(s):")
byType.forEach { (type, species) -> println(" $type: ${species.distinct().joinToString(", ")}") }
player?.sendSystemMessage(Component.literal("Evolution render debug: ${gaps.size} gap(s) across ${byType.size} type(s), see log for details."))
}
@@ -0,0 +1,123 @@
/*
* 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.gui.pokedex.widgets.evolutiontree
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
import com.cobblemon.mod.common.api.text.green
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.DummyEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.itemRegistry
import com.cobblemon.mod.common.util.lang
import net.minecraft.client.Minecraft
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.world.item.Item
data class RenderEvolutionData(
val icons: List<Item>,
val tooltips: List<MutableComponent>,
)
internal fun resolveRequirementData(requirement: Requirement): RenderRequirementData? {
val icon = requirement.pokedexIcon?.let {
Minecraft.getInstance()?.player?.level()?.itemRegistry?.get(it)
}
val tooltip = requirement.pokedexTooltip?.let {
Component.translatable(it)
}
if (icon != null && tooltip != null) {
return RenderRequirementData(icon, tooltip)
}
return renderRequirementData(requirement)
}
fun renderEvolutionData(evolution: Evolution): RenderEvolutionData? {
when (evolution) {
is BlockClickEvolution -> return renderBlockClickEvolution(evolution)
is DummyEvolution -> return renderDummyEvolution(evolution)
is ItemInteractionEvolution -> return renderItemInteractionEvolution(evolution)
is LevelUpEvolution -> return renderLevelUpEvolution(evolution)
is TradeEvolution -> return renderTradeEvolution(evolution)
}
return null
}
fun renderBlockClickEvolution(blockClickEvolution: BlockClickEvolution): RenderEvolutionData? {
return null
}
// TODO: Use dummyEvolution?
fun renderDummyEvolution(evolution: Evolution): RenderEvolutionData? {
return null
}
fun renderItemInteractionEvolution(itemInteractionEvolution: ItemInteractionEvolution): RenderEvolutionData? {
val item = itemInteractionEvolution.requiredContext.items.get().first().value()
val icons = mutableListOf(item)
val tooltips =
mutableListOf(lang("ui.pokedex.evolution.item_interact.tooltip", item.description.plainCopy().green()))
val requirementsDataList = itemInteractionEvolution.requirements.mapNotNull { requirement ->
resolveRequirementData(requirement)
}
requirementsDataList.forEach { requirement ->
icons.add(requirement.icon)
tooltips.add(requirement.tooltip)
}
return RenderEvolutionData(icons, tooltips)
}
fun renderLevelUpEvolution(levelUpEvolution: LevelUpEvolution): RenderEvolutionData? {
val requirementsDataList = levelUpEvolution.requirements.map { requirement ->
resolveRequirementData(requirement)
}
val icons = requirementsDataList.mapNotNull { requirementData -> requirementData?.icon }
val tooltips = requirementsDataList.mapNotNull { requirementData -> requirementData?.tooltip }
return RenderEvolutionData(icons, tooltips)
}
fun renderTradeEvolution(tradeEvolution: TradeEvolution): RenderEvolutionData? {
val icons = mutableListOf<Item>(CobblemonItems.LINK_CABLE)
val tooltips = mutableListOf<MutableComponent>()
val species = tradeEvolution.requiredContext.species
if (species == null) {
tooltips.add(lang("ui.pokedex.evolution.trade.tooltip.with_any_species"))
} else {
PokemonSpecies.getByIdentifier(cobblemonResource(species))?.let {
tooltips.add(lang("ui.pokedex.evolution.trade.tooltip.with_species", it.translatedName.green()))
}
}
val requirementsDataList = tradeEvolution.requirements.mapNotNull { requirement ->
resolveRequirementData(requirement)
}
requirementsDataList.forEach { requirement ->
icons.add(requirement.icon)
tooltips.add(requirement.tooltip)
}
return RenderEvolutionData(icons, tooltips)
}
@@ -0,0 +1,379 @@
/*
* 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.gui.pokedex.widgets.evolutiontree
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
import com.cobblemon.mod.common.api.conditional.RegistryLikeTagCondition
import com.cobblemon.mod.common.api.pokemon.feature.IntSpeciesFeatureProvider
import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.api.text.add
import com.cobblemon.mod.common.api.text.green
import com.cobblemon.mod.common.api.text.red
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.pokemon.requirements.*
import com.cobblemon.mod.common.util.asTranslated
import com.cobblemon.mod.common.util.lang
import net.minecraft.client.Minecraft
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.world.item.Item
import net.minecraft.world.item.Items
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.levelgen.structure.Structure
data class RenderRequirementData(
val icon: Item,
val tooltip: MutableComponent,
)
fun renderRequirementData(requirement: Requirement): RenderRequirementData? {
when (requirement) {
is AdvancementRequirement -> return renderAdvancementRequirement(requirement)
is AnyRequirement -> return renderAnyRequirement(requirement)
is AreaRequirement -> return renderAreaRequirement(requirement)
is AttackDefenceRatioRequirement -> return renderAttackDefenceRatioRequirement(requirement)
is BattleCriticalHitsRequirement -> return renderBattleCriticalHitsRequirement(requirement)
is BiomeRequirement -> return renderBiomeRequirement(requirement)
is BlocksTraveledRequirement -> return renderBlocksTraveledRequirement(requirement)
is DamageTakenRequirement -> return renderDamageTakenRequirement(requirement)
is DefeatRequirement -> return renderDefeatRequirement(requirement)
is FriendshipRequirement -> return renderFriendshipRequirement(requirement)
is HeldItemRequirement -> return renderHeldItemRequirement(requirement)
is LevelRequirement -> return renderLevelRequirement(requirement)
is MoonPhaseRequirement -> return renderMoonPhaseRequirement(requirement)
is MoveSetRequirement -> return renderMoveSetRequirement(requirement)
is MoveTypeRequirement -> return renderMoveTypeRequirement(requirement)
is OwnerHoldsItemRequirement -> return renderOwnerHoldsItemRequirement(requirement)
is PartyMemberRequirement -> return renderPartyMemberRequirement(requirement)
is PokemonPropertiesRequirement -> return renderPokemonPropertiesRequirement(requirement)
is PropertyRangeRequirement -> return renderPropertyRangeRequirement(requirement)
is RecoilRequirement -> return renderRecoilRequirement(requirement)
is StatCompareRequirement -> return renderStatCompareRequirement(requirement)
is StatEqualRequirement -> return renderStatEqualRequirement(requirement)
is StructureRequirement -> return renderStructureRequirement(requirement)
is TimeRangeRequirement -> return renderTimeRangeRequirement(requirement)
is UseMoveRequirement -> return renderUseMoveRequirement(requirement)
is WeatherRequirement -> return renderWeatherRequirement(requirement)
is WorldRequirement -> return renderWorldRequirement(requirement)
}
return null
}
fun renderAdvancementRequirement(advancementRequirement: AdvancementRequirement): RenderRequirementData? {
val icon = Items.BOOK
val identifier = advancementRequirement.requiredAdvancement
val advancementLanguageKey = "${identifier.namespace}.${identifier.path.substringAfterLast('/')}"
val advancementComponent = Component.translatable("advancements.$advancementLanguageKey").green()
val tooltip = lang("ui.pokedex.requirement.advancement.tooltip", advancementComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderAnyRequirement(anyRequirement: AnyRequirement): RenderRequirementData? {
return null
}
fun renderAreaRequirement(areaRequirement: AreaRequirement): RenderRequirementData? {
return null
}
fun renderAttackDefenceRatioRequirement(attackDefenceRatioRequirement: AttackDefenceRatioRequirement): RenderRequirementData? {
return null
}
fun renderBattleCriticalHitsRequirement(battleCriticalHitsRequirement: BattleCriticalHitsRequirement): RenderRequirementData? {
val icon = CobblemonItems.MEDICINAL_LEEK
val criticalsComponent = Component.literal(battleCriticalHitsRequirement.amount.toString()).green()
val tooltip = lang("ui.pokedex.requirement.battle_critical_hits.tooltip", criticalsComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderBiomeRequirement(biomeRequirement: BiomeRequirement): RenderRequirementData? {
val condition = biomeRequirement.biomeCondition
val anticondition = biomeRequirement.biomeAnticondition
if (condition == null && anticondition == null) {
return null
}
val icon = Items.COMPASS
val displayName: (RegistryLikeCondition<Biome>) -> MutableComponent = {
when (it) {
is RegistryLikeTagCondition -> Component.literal(it.tag.location().path.substringAfterLast('/').split('_').joinToString(" ") { part -> part.replaceFirstChar(Char::titlecase) })
is RegistryLikeIdentifierCondition -> Component.translatable("biome.${it.identifier.namespace}.${it.identifier.path}")
else -> Component.literal(it.toString())
}
}
val tooltip = if (condition != null && anticondition != null) {
lang("ui.pokedex.requirement.biome.both.tooltip", displayName(condition).green(), displayName(anticondition).green())
} else if (condition != null) {
lang("ui.pokedex.requirement.biome.tooltip", displayName(condition).green())
} else {
lang("ui.pokedex.requirement.biome.anticondition.tooltip", displayName(anticondition!!).green())
}
val playerBiome = Minecraft.getInstance()?.player?.let { it.level().getBiome(it.blockPosition()) }
if (playerBiome != null) {
val isMet = (condition == null || condition.fits(playerBiome)) && (anticondition == null || !anticondition.fits(playerBiome))
tooltip.add(if (isMet) Component.literal(" ✔").green() else Component.literal(" ✘").red())
}
return RenderRequirementData(icon, tooltip)
}
fun renderBlocksTraveledRequirement(blocksTraveledRequirement: BlocksTraveledRequirement): RenderRequirementData? {
val icon = Items.LEATHER_BOOTS
val blocksComponent = Component.literal(blocksTraveledRequirement.amount.toString()).green()
val tooltip = lang("ui.pokedex.requirement.blocks_traveled.tooltip", blocksComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderDamageTakenRequirement(damageTakenRequirement: DamageTakenRequirement): RenderRequirementData? {
val icon = CobblemonItems.PUNCHING_GLOVE
val blocksComponent = Component.literal(damageTakenRequirement.amount.toString()).green()
val tooltip = lang("ui.pokedex.requirement.damage_taken.tooltip", blocksComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderDefeatRequirement(defeatRequirement: DefeatRequirement): RenderRequirementData? {
val description = describePokemonProperties(defeatRequirement.target) ?: return null
val icon = CobblemonItems.PUNCHING_GLOVE
val defeatedAmount = defeatRequirement.amount
val descriptionComponent = Component.literal(defeatedAmount.toString()).green().add(" ").add(description)
val tooltip = lang("ui.pokedex.requirement.defeat.tooltip", descriptionComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderFriendshipRequirement(friendshipRequirement: FriendshipRequirement): RenderRequirementData? {
val icon = CobblemonItems.SOOTHE_BELL
val friendshipAmountComponent = Component.literal(friendshipRequirement.amount.toString()).green()
val tooltip = lang("ui.pokedex.requirement.friendship.tooltip", friendshipAmountComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderHeldItemRequirement(heldItemRequirement: HeldItemRequirement): RenderRequirementData? {
val item = heldItemRequirement.itemCondition.items.get().first().value()
val tooltip = lang("ui.pokedex.requirement.held_item.tooltip", item.description.plainCopy().green())
return RenderRequirementData(item, tooltip)
}
fun renderLevelRequirement(levelRequirement: LevelRequirement): RenderRequirementData? {
val minLevel = levelRequirement.minLevel
val maxLevel = levelRequirement.maxLevel
val icon = CobblemonItems.RARE_CANDY
val tooltip =
if (minLevel == maxLevel || maxLevel == Int.MAX_VALUE)
lang("ui.pokedex.requirement.level.tooltip.min", Component.literal(minLevel.toString()).green())
else
lang("ui.pokedex.requirement.level.tooltip.between", Component.literal(minLevel.toString()).green(), Component.literal(maxLevel.toString()).green())
return RenderRequirementData(icon, tooltip)
}
fun renderMoonPhaseRequirement(moonPhaseRequirement: MoonPhaseRequirement): RenderRequirementData? {
val icon = Items.CLOCK
val moonPhaseComponent = moonPhaseRequirement.moonPhase.displayName().green()
val tooltip = lang("ui.pokedex.requirement.moon_phase.tooltip", moonPhaseComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderMoveSetRequirement(moveSetRequirement: MoveSetRequirement): RenderRequirementData? {
val icon = CobblemonItems.TECHNICAL_MACHINE
val tooltip = lang("ui.pokedex.requirement.has_move.tooltip", moveSetRequirement.move.displayName.green())
return RenderRequirementData(icon, tooltip)
}
fun renderMoveTypeRequirement(moveTypeRequirement: MoveTypeRequirement): RenderRequirementData? {
val type = ElementalTypes.get(moveTypeRequirement.type.name)
val icon = when (type) {
ElementalTypes.NORMAL -> CobblemonItems.NORMAL_GEM
ElementalTypes.FIRE -> CobblemonItems.FIRE_GEM
ElementalTypes.WATER -> CobblemonItems.WATER_GEM
ElementalTypes.GRASS -> CobblemonItems.GRASS_GEM
ElementalTypes.ELECTRIC -> CobblemonItems.ELECTRIC_GEM
ElementalTypes.ICE -> CobblemonItems.ICE_GEM
ElementalTypes.FIGHTING -> CobblemonItems.FIGHTING_GEM
ElementalTypes.POISON -> CobblemonItems.POISON_GEM
ElementalTypes.GROUND -> CobblemonItems.GROUND_GEM
ElementalTypes.FLYING -> CobblemonItems.FLYING_GEM
ElementalTypes.PSYCHIC -> CobblemonItems.PSYCHIC_GEM
ElementalTypes.BUG -> CobblemonItems.BUG_GEM
ElementalTypes.ROCK -> CobblemonItems.ROCK_GEM
ElementalTypes.GHOST -> CobblemonItems.GHOST_GEM
ElementalTypes.DRAGON -> CobblemonItems.DRAGON_GEM
ElementalTypes.DARK -> CobblemonItems.DARK_GEM
ElementalTypes.STEEL -> CobblemonItems.STEEL_GEM
ElementalTypes.FAIRY -> CobblemonItems.FAIRY_GEM
else -> CobblemonItems.NORMAL_GEM
}
val tooltip = lang("ui.pokedex.requirement.has_move_type.tooltip", moveTypeRequirement.type.displayName.green())
return RenderRequirementData(icon, tooltip)
}
fun renderOwnerHoldsItemRequirement(ownerHoldsItemRequirement: OwnerHoldsItemRequirement): RenderRequirementData? {
val item = ownerHoldsItemRequirement.itemCondition.items.get().first().value()
val tooltip = lang("ui.pokedex.requirement.owner_held_item.tooltip", item.description.plainCopy().green())
return RenderRequirementData(item, tooltip)
}
fun renderPartyMemberRequirement(partyMemberRequirement: PartyMemberRequirement): RenderRequirementData? {
val description = describePokemonProperties(partyMemberRequirement.target) ?: return null
val icon = CobblemonItems.POKE_BALL
val tooltip = if (partyMemberRequirement.contains) {
lang("ui.pokedex.requirement.party_member.tooltip", description)
} else {
lang("ui.pokedex.requirement.party_member.anticondition.tooltip", description)
}
return RenderRequirementData(icon, tooltip)
}
fun renderPokemonPropertiesRequirement(pokemonPropertiesRequirement: PokemonPropertiesRequirement): RenderRequirementData? {
val description = describePokemonProperties(pokemonPropertiesRequirement.target) ?: return null
val icon = Items.NAME_TAG
val tooltip = lang("ui.pokedex.requirement.pokemon_properties.tooltip", description)
return RenderRequirementData(icon, tooltip)
}
fun renderPropertyRangeRequirement(propertyRangeRequirement: PropertyRangeRequirement): RenderRequirementData? {
val provider = SpeciesFeatures.getFeature(propertyRangeRequirement.feature) as? IntSpeciesFeatureProvider ?: return null
val displayName = provider.display?.name?.takeIf { it.isNotBlank() }?.asTranslated()?.green() ?: return null
val icon = provider.itemPoints.keys.firstOrNull()?.let { BuiltInRegistries.ITEM.get(it) } ?: Items.NAME_TAG
val range = propertyRangeRequirement.range
val tooltip = lang(
"ui.pokedex.requirement.property_range.tooltip",
displayName,
Component.literal(range.first.toString()).green(),
Component.literal(range.last.toString()).green()
)
return RenderRequirementData(icon, tooltip)
}
fun renderRecoilRequirement(recoilRequirement: RecoilRequirement): RenderRequirementData? {
val icon = CobblemonItems.LIFE_ORB
val recoilComponent = Component.literal(recoilRequirement.amount.toString()).green()
val tooltip = lang("ui.pokedex.requirement.recoil.tooltip", recoilComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderStatCompareRequirement(statCompareRequirement: StatCompareRequirement): RenderRequirementData? {
val highStat = Stats.getStat(statCompareRequirement.highStat)
val lowStat = Stats.getStat(statCompareRequirement.lowStat)
val icon = when (highStat) {
Stats.HP, Stats.EVASION, Stats.ACCURACY -> CobblemonItems.HEALTH_MOCHI
Stats.ATTACK -> CobblemonItems.MUSCLE_MOCHI
Stats.DEFENCE -> CobblemonItems.RESIST_MOCHI
Stats.SPECIAL_ATTACK -> CobblemonItems.GENIUS_MOCHI
Stats.SPECIAL_DEFENCE -> CobblemonItems.CLEVER_MOCHI
Stats.SPEED -> CobblemonItems.SWIFT_MOCHI
}
val highStatComponent = highStat.displayName.plainCopy().green()
val lowStatComponent = lowStat.displayName.plainCopy().green()
val tooltip = lang("ui.pokedex.requirement.stat_compare.tooltip", highStatComponent, lowStatComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderStatEqualRequirement(statEqualRequirement: StatEqualRequirement): RenderRequirementData? {
val statOne = Stats.getStat(statEqualRequirement.statOne)
val statTwo = Stats.getStat(statEqualRequirement.statTwo)
val statOneComponent = statOne.displayName.plainCopy().green()
val statTwoComponent = statTwo.displayName.plainCopy().green()
val icon = CobblemonItems.FRESH_START_MOCHI
val tooltip = lang("ui.pokedex.requirement.stat_equal.tooltip", statOneComponent, statTwoComponent)
return RenderRequirementData(icon, tooltip)
}
fun renderStructureRequirement(structureRequirement: StructureRequirement): RenderRequirementData? {
val condition = structureRequirement.structureCondition
val anticondition = structureRequirement.structureAnticondition
if (condition == null && anticondition == null) {
return null
}
val icon = Items.STRUCTURE_BLOCK
val displayName: (RegistryLikeCondition<Structure>) -> MutableComponent = {
val path = when (it) {
is RegistryLikeTagCondition -> it.tag.location().path
is RegistryLikeIdentifierCondition -> it.identifier.path
else -> it.toString()
}
Component.literal(path.substringAfterLast('/').split('_').joinToString(" ") { part -> part.replaceFirstChar(Char::titlecase) })
}
val tooltip = if (condition != null && anticondition != null) {
lang("ui.pokedex.requirement.structure.both.tooltip", displayName(condition).green(), displayName(anticondition).green())
} else if (condition != null) {
lang("ui.pokedex.requirement.structure.tooltip", displayName(condition).green())
} else {
lang("ui.pokedex.requirement.structure.anticondition.tooltip", displayName(anticondition!!).green())
}
return RenderRequirementData(icon, tooltip)
}
fun renderTimeRangeRequirement(timeRangeRequirement: TimeRangeRequirement): RenderRequirementData? {
val icon = Items.CLOCK
val timeRangeComponent = timeRangeRequirement.range.displayName() ?: return null
val tooltip = lang("ui.pokedex.requirement.time_range.tooltip", timeRangeComponent.green())
return RenderRequirementData(icon, tooltip)
}
fun renderUseMoveRequirement(useMoveRequirement: UseMoveRequirement): RenderRequirementData? {
val icon = CobblemonItems.CHOICE_BAND
val tooltip = lang("ui.pokedex.requirement.use_move.tooltip", useMoveRequirement.move.displayName.green())
return RenderRequirementData(icon, tooltip)
}
fun renderWeatherRequirement(weatherRequirement: WeatherRequirement): RenderRequirementData? {
val icon: Item
val tooltip: MutableComponent
if (weatherRequirement.isThundering == true) {
icon = Items.LIGHTNING_ROD
tooltip = lang("ui.pokedex.requirement.weather.tooltip.thundering")
} else {
icon = Items.WATER_BUCKET
tooltip = lang("ui.pokedex.requirement.weather.tooltip.raining")
}
return RenderRequirementData(icon, tooltip)
}
fun renderWorldRequirement(worldRequirement: WorldRequirement): RenderRequirementData? {
return null
}
@@ -0,0 +1,571 @@
/*
* 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.gui.pokedex.widgets.evolutiontree
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.gui.*
import com.cobblemon.mod.common.api.pokedex.Dexes
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.entry.PokedexEntry
import com.cobblemon.mod.common.api.pokedex.entry.PokedexForm
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.text.add
import com.cobblemon.mod.common.api.text.bold
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUI
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.HALF_OVERLAY_WIDTH
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.POKEMON_DESCRIPTION_HEIGHT
import com.cobblemon.mod.common.client.gui.pokedex.PokedexGUIConstants.SCROLL_SLOT_SIZE
import com.cobblemon.mod.common.client.gui.pokedex.ScaledButton
import com.cobblemon.mod.common.client.gui.pokedex.renderTooltip
import com.cobblemon.mod.common.client.gui.pokedex.widgets.PokemonSlotWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.renderScaledGuiItemIcon
import com.cobblemon.mod.common.pokemon.Gender
import com.cobblemon.mod.common.pokemon.RenderablePokemon
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
class EvolutionTreeWidget(
val parent: PokedexGUI,
val pX: Int,
val pY: Int,
) : SoundlessWidget(
pX, pY,
HALF_OVERLAY_WIDTH,
POKEMON_DESCRIPTION_HEIGHT,
lang("ui.pokedex.pokemon_info")
) {
companion object {
private val slotResource = cobblemonResource("textures/gui/pokedex/pokedex_slot.png")
private val expandResource = cobblemonResource("textures/gui/pokedex/expand.png")
private val minimizeResource = cobblemonResource("textures/gui/pokedex/minimize.png")
const val X_MARGIN = 180
const val Y_MARGIN_MINIMIZED = 135
const val Y_MARGIN_EXPANDED = 53
const val EXPANDED_HEIGHT = 125
const val HORIZONTAL_PADDING = 38
const val VERTICAL_PADDING = 2
const val TREE_FORK_LENGTH = 4
const val ICON_X_PADDING = -4.0
const val ICON_Y_PADDING = -4.0
const val MILLIS_BETWEEN_ICONS_CYCLE = 1000
const val ICON_SLOT_BACKGROUND_SIZE = 8
const val ICON_SLOT_PADDING = 4
const val ICON_SLOT_HALF_PADDING = ICON_SLOT_PADDING / 2
const val LINE_COLOR = 0xff1d6b85.toInt()
const val EXPAND_BUTTON_X_MARGIN = 127f
const val EXPAND_BUTTON_Y_MARGIN = -10.5f
const val EXPAND_BUTTON_SIZE = 20
private var previousRootPokedexEntry: PokedexEntry? = null
private var previousRootPokedexForm: PokedexForm? = null
}
private var rootTreeDrawingNode: TreeDrawingNode<EvolutionNode>? = null
private var treeDrawingBounds: TreeDrawingBounds? = null
private var zoomLevel: Double = 0.0
private var panningX: Double = 0.0
private var panningY: Double = 0.0
private var hoveredTooltips: List<MutableComponent>? = null
private val expandButton: ScaledButton = ScaledButton(
0f,
0f,
EXPAND_BUTTON_SIZE,
EXPAND_BUTTON_SIZE,
resource = expandResource,
clickAction = {
parent.evolutionTreeExpanded = !parent.evolutionTreeExpanded
expandButton.resource = if (parent.evolutionTreeExpanded) minimizeResource else expandResource
updatePositioning()
}
).apply { addWidget(this) }
override fun renderWidget(
guiGraphics: GuiGraphics,
mouseX: Int,
mouseY: Int,
partialTick: Float,
) {
drawScaledText(
context = guiGraphics,
font = CobblemonResources.DEFAULT_LARGE,
text = Component.translatable("cobblemon.ui.pokedex.info.evolution_tree").bold(),
x = x + 9,
y = y - 10,
shadow = true
)
expandButton.render(guiGraphics, mouseX, mouseY, partialTick)
rootTreeDrawingNode?.let {
enableScissors(guiGraphics)
renderTreeDrawingNode(guiGraphics, it, mouseX, mouseY, partialTick)
guiGraphics.disableScissor()
hoveredTooltips?.let { tooltips ->
renderTooltip(
guiGraphics,
tooltips,
mouseX,
mouseY,
partialTick,
4,
)
}
hoveredTooltips = null
}
}
fun setup(pokedexEntry: PokedexEntry?, pokedexForm: PokedexForm?) {
if (pokedexEntry == null || pokedexForm == null) return
updatePositioning()
val (rootPokedexEntry, rootPokedexForm) = Dexes.findRootDexEntryBySpeciesId(pokedexEntry.speciesId, pokedexForm.displayForm)
val rootEvolutionNode = buildEvolutionTree(rootPokedexEntry, rootPokedexForm, null)
// val isSameEntry = previousRootPokedexEntry != null && pokedexEntry?.id == previousRootPokedexEntry?.id
// val isSameForm =
// previousRootPokedexForm != null && pokedexForm?.displayForm == previousRootPokedexForm?.displayForm
// TODO: figure out how to prevent pokedex from resetting all the widgets state
// if (isSameEntry && isSameForm) {
// return
// }
previousRootPokedexEntry = pokedexEntry
previousRootPokedexForm = pokedexForm
createDrawingTree(rootEvolutionNode).also {
rootTreeDrawingNode = it
treeDrawingBounds = calculateBounds<EvolutionNode>(it)
}
zoomLevel = 0.0
panningX = 0.0
panningY = 0.0
}
fun updatePositioning() {
x = pX + X_MARGIN
y = pY + if (parent.evolutionTreeExpanded) Y_MARGIN_EXPANDED else Y_MARGIN_MINIMIZED
height = if (parent.evolutionTreeExpanded) EXPANDED_HEIGHT else POKEMON_DESCRIPTION_HEIGHT
panningX = 0.0
panningY = 0.0
expandButton.buttonX = x + EXPAND_BUTTON_X_MARGIN
expandButton.buttonY = y + EXPAND_BUTTON_Y_MARGIN
}
private fun buildEvolutionTree(
pokedexEntry: PokedexEntry,
pokedexForm: PokedexForm,
evolution: Evolution? = null,
resultProperties: PokemonProperties? = evolution?.result,
renderData: RenderEvolutionData? = evolution?.let { renderEvolutionData(it) }
): EvolutionNode {
val species = PokemonSpecies.getByIdentifier(pokedexEntry.speciesId)!!
val formEquivalents = Dexes.getFormEquivalents(pokedexForm.displayForm)
val form = species.forms.firstOrNull { formEquivalents.contains(it.name.lowercase()) }
val parentSpecies = Dexes.findDexEntryBySpeciesId(species.resourceIdentifier)!!
val parentPokedexForm = parentSpecies.forms.first { formEquivalents.contains(it.displayForm.lowercase()) }
val aspects = resultProperties?.aspects?.toMutableSet() ?: mutableSetOf()
form?.aspects?.let { aspects.addAll(it) }
val discoveryLevel = CobblemonClient.clientPokedexData.getHighestKnowledgeFor(pokedexEntry, pokedexForm, aspects)
val evolutions = form?.evolutions ?: species.evolutions
// Avoid evolution.result.create() here: it builds a full battle-ready Pokemon (initializeMovesetFromDefault
// etc.) which relies on server-only data like CobblemonMovesetBuilders and crashes on the client
val children = evolutions.flatMap { evolution ->
val baseRenderData = renderEvolutionData(evolution)
listOfNotNull(evolution.result, evolution.shedder).mapNotNull { resultProperties ->
val resultSpecies = resultProperties.species
?.let { PokemonSpecies.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
?: return@mapNotNull null
val resultForm = resultSpecies.getForm(aspects + resultProperties.aspects)
val speciesId = resultSpecies.resourceIdentifier
val childPokedexEntry = Dexes.findDexEntryBySpeciesId(speciesId)
if (childPokedexEntry == null) {
Cobblemon.LOGGER.warn("Dex entry not found for species: $speciesId")
return@mapNotNull null
}
val formEquivalents = Dexes.getFormEquivalents(resultForm.name.lowercase())
val childPokedexForm = childPokedexEntry.forms.first { formEquivalents.contains(it.displayForm.lowercase()) }
val childRenderData = if (resultProperties === evolution.shedder) {
RenderEvolutionData(
icons = (baseRenderData?.icons ?: emptyList()) + CobblemonItems.POKE_BALL,
tooltips = (baseRenderData?.tooltips ?: emptyList()) + lang("ui.pokedex.evolution.shedder.tooltip"),
)
} else {
baseRenderData
}
return@mapNotNull buildEvolutionTree(childPokedexEntry, childPokedexForm, evolution, resultProperties, childRenderData)
}
}
return EvolutionNode(pokedexEntry, parentPokedexForm, aspects, discoveryLevel, children, renderData)
}
private fun renderTreeDrawingNode(
guiGraphics: GuiGraphics,
treeDrawingNode: TreeDrawingNode<EvolutionNode>,
mouseX: Int,
mouseY: Int,
delta: Float,
) {
val (treeX, treeY) = getDrawingCoordinates(treeDrawingNode)
if (treeDrawingNode.children.size == 1) {
val child = treeDrawingNode.children.first()
val (childX, _) = getDrawingCoordinates(child)
val lineStartX = treeX + SCROLL_SLOT_SIZE
val lineEndX = childX
val lineY = treeY + SCROLL_SLOT_SIZE / 2
child.value.renderData?.let { renderData ->
drawEvolutionInfo(
guiGraphics,
renderData,
lineStartX,
lineEndX,
lineY,
mouseX,
mouseY,
delta,
)
}
} else if (treeDrawingNode.children.size > 1) {
val treeForkStart = treeX + SCROLL_SLOT_SIZE
val treeForkEnd = treeX + SCROLL_SLOT_SIZE + TREE_FORK_LENGTH
val middleStart = treeY + SCROLL_SLOT_SIZE / 2
val (_, firstChildY) = getDrawingCoordinates(treeDrawingNode.children.first())
val (_, lastChildY) = getDrawingCoordinates(treeDrawingNode.children.last())
guiGraphics.hLine(
treeForkStart,
treeForkEnd,
middleStart,
LINE_COLOR,
)
guiGraphics.vLine(
treeForkEnd,
firstChildY + SCROLL_SLOT_SIZE / 2,
lastChildY + SCROLL_SLOT_SIZE / 2,
LINE_COLOR,
)
treeDrawingNode.children.forEach { child ->
val (childX, childY) = getDrawingCoordinates(child)
val lineStartX = treeForkEnd
val lineEndX = childX
val lineY = childY + SCROLL_SLOT_SIZE / 2
child.value.renderData?.let { renderData ->
drawEvolutionInfo(
guiGraphics,
renderData,
lineStartX,
lineEndX,
lineY,
mouseX,
mouseY,
delta,
)
}
}
}
treeDrawingNode.children.forEach { child ->
renderTreeDrawingNode(guiGraphics, child, mouseX, mouseY, delta)
}
val isVisible =
treeX >= x - SCROLL_SLOT_SIZE &&
treeX <= x + width &&
treeY >= y - SCROLL_SLOT_SIZE &&
treeY <= y + height
if (!isVisible) return
val evolutionNode = treeDrawingNode.value
val isSlotHovered =
isElementHovered(mouseX, mouseY, treeX, treeX + SCROLL_SLOT_SIZE, treeY, treeY + SCROLL_SLOT_SIZE)
val discoveryLevel = evolutionNode.pokedexEntryProgress
if (isSlotHovered) {
val text =
if (discoveryLevel == PokedexEntryProgress.UNREGISTERED) {
lang("ui.pokedex.unknown")
} else {
val species = PokemonSpecies.getByIdentifier(evolutionNode.pokedexEntry.speciesId)!!
val speciesComponent = species.translatedName
val formName = evolutionNode.pokedexForm.displayForm.lowercase()
val formComponent =
if (formName == "normal") null
else lang("ui.pokedex.info.form.${species}-${formName.replace("-", "")}")
formComponent?.add(" ")?.add(speciesComponent) ?: speciesComponent
}
guiGraphics.disableScissor()
renderTooltip(
context = guiGraphics,
text = text,
posX = mouseX,
posY = mouseY,
delta,
4,
)
enableScissors(guiGraphics)
}
val pokedexEntry = evolutionNode.pokedexEntry
val pokedexForm = evolutionNode.pokedexForm
val species = PokemonSpecies.getByIdentifier(evolutionNode.pokedexEntry.speciesId)!!
val encounteredForms = CobblemonClient.clientPokedexData.getEncounteredForms(pokedexEntry)
val formToRender = encounteredForms.firstOrNull { it.displayForm.equals(pokedexForm.displayForm, ignoreCase = true) }
val renderablePokemon =
if (formToRender != null) {
val seenGenders = CobblemonClient.clientPokedexData.getSeenGenders(pokedexEntry, formToRender)
val seenShinyStates = CobblemonClient.clientPokedexData.getSeenShinyStates(pokedexEntry, formToRender)
val aspectsToDraw = (pokedexEntry.displayAspects + evolutionNode.aspects).toMutableSet()
val formAspects = species.forms.firstOrNull { it.name.equals(formToRender.displayForm, ignoreCase = true) }?.aspects
if (formAspects != null) {
aspectsToDraw.addAll(formAspects)
}
if (seenGenders.contains(parent.gender)) {
aspectsToDraw.add(parent.gender.name.lowercase())
} else {
aspectsToDraw.add((seenGenders.firstOrNull() ?: Gender.GENDERLESS).name.lowercase())
}
if (parent.shiny && seenShinyStates.contains("shiny")) {
aspectsToDraw.add("shiny")
}
RenderablePokemon(species, aspectsToDraw)
} else {
null
}
PokemonSlotWidget.render(
context = guiGraphics,
x = treeX,
y = treeY,
isHovered = isSlotHovered,
species = species,
renderablePokemon = renderablePokemon,
discoveryLevel = discoveryLevel,
)
}
private fun drawEvolutionInfo(
guiGraphics: GuiGraphics,
renderData: RenderEvolutionData,
lineStartX: Int,
lineEndX: Int,
lineY: Int,
mouseX: Int,
mouseY: Int,
delta: Float,
) {
val lineXMiddle = (lineStartX + lineEndX) / 2
val iconX = (lineXMiddle + ICON_X_PADDING - ICON_SLOT_HALF_PADDING).toInt()
val iconY = (lineY + ICON_Y_PADDING - ICON_SLOT_HALF_PADDING).toInt()
val iconSize = ICON_SLOT_BACKGROUND_SIZE + ICON_SLOT_PADDING
val isVisible =
iconX >= x - iconSize &&
iconX <= x + width &&
iconY >= y - iconSize &&
iconY <= y + height
if (!isVisible) {
return
}
if (renderData.icons.isEmpty()) {
guiGraphics.hLine(
lineStartX,
lineEndX,
lineY,
LINE_COLOR,
)
} else {
guiGraphics.hLine(
lineStartX,
iconX - 1,
lineY,
LINE_COLOR,
)
guiGraphics.hLine(
iconX + iconSize,
lineEndX,
lineY,
LINE_COLOR,
)
blitk(
matrixStack = guiGraphics.pose(),
texture = slotResource,
x = iconX,
y = iconY,
width = iconSize,
height = iconSize,
)
val index = (System.currentTimeMillis() / MILLIS_BETWEEN_ICONS_CYCLE) % renderData.icons.size
val item = renderData.icons[index.toInt()]
renderScaledGuiItemIcon(
itemStack = item.defaultInstance,
x = lineXMiddle + ICON_X_PADDING,
y = lineY + ICON_Y_PADDING,
matrixStack = guiGraphics.pose(),
scale = PokedexGUIConstants.SCALE.toDouble(),
)
}
val isLineHovered = isElementHovered(mouseX, mouseY, lineStartX, lineEndX, lineY - 1, lineY + 1)
val isIconHovered = isElementHovered(
mouseX,
mouseY,
iconX.toInt(),
iconX.toInt() + iconSize,
iconY.toInt(),
iconY.toInt() + iconSize,
)
if (renderData.tooltips.isNotEmpty() &&
(isLineHovered || isIconHovered) &&
this.isHovered(mouseX.toDouble(), mouseY.toDouble())
) {
hoveredTooltips = renderData.tooltips
}
}
private fun getDrawingCoordinates(node: TreeDrawingNode<EvolutionNode>): Pair<Int, Int> {
val halfSlot = SCROLL_SLOT_SIZE / 2f
val xStep = halfSlot + HORIZONTAL_PADDING
val yStep = halfSlot + VERTICAL_PADDING
// Swaps the x and y to draw the tree horizontally
val xDislocation = (node.y - treeDrawingBounds!!.yCenter) * xStep
val yDislocation = (node.x - treeDrawingBounds!!.xCenter) * yStep
val xCenter = width / 2f - halfSlot
val yCenter = height / 2f - halfSlot
val screenX = (xCenter.toInt() + xDislocation.toInt() + panningX.toInt() + x)
val screenY = (yCenter.toInt() + yDislocation.toInt() + panningY.toInt() + y)
return screenX to screenY
}
private fun isElementHovered(
mouseX: Int,
mouseY: Int,
startX: Int,
endX: Int,
startY: Int,
endY: Int,
): Boolean {
return mouseX >= startX && mouseX <= endX && mouseY >= startY && mouseY <= endY
}
override fun mouseDragged(
mouseX: Double,
mouseY: Double,
button: Int,
deltaX: Double,
deltaY: Double
): Boolean {
panningX += deltaX
panningY += deltaY
val bounds = treeDrawingBounds ?: return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
val treeHeight = bounds.height.coerceAtLeast(1)
val treeWidth = bounds.width.coerceAtLeast(1)
val xStep = HORIZONTAL_PADDING + SCROLL_SLOT_SIZE / 2.0
val yStep = VERTICAL_PADDING + SCROLL_SLOT_SIZE / 2.0
val minPanningX = (treeHeight - 1) * -xStep / 2.0 - (width + SCROLL_SLOT_SIZE) / 2.0
val maxPanningX = (treeHeight - 1) * xStep / 2.0 + (width + SCROLL_SLOT_SIZE) / 2.0
val divideBy = if (treeWidth % 2 == 0) 4.0 else 2.0
val minPanningY = (treeWidth - 1) * -yStep / 2.0 - height / 2.0 + SCROLL_SLOT_SIZE / divideBy
val maxPanningY = (treeWidth - 1) * yStep / 2.0 + height / 2.0 - SCROLL_SLOT_SIZE / divideBy
panningX = panningX.coerceIn(minPanningX, maxPanningX)
panningY = panningY.coerceIn(minPanningY, maxPanningY)
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
fun isHovered(mouseX: Double, mouseY: Double): Boolean {
return mouseX.toInt() in x..(x + width) && mouseY.toInt() in y..(y + height)
}
fun enableScissors(guiGraphics: GuiGraphics) {
guiGraphics.enableScissor(x + 1, y, x + width - 1, y + height)
}
private class EvolutionNode(
val pokedexEntry: PokedexEntry,
val pokedexForm: PokedexForm,
val aspects: Set<String>,
val pokedexEntryProgress: PokedexEntryProgress,
override val children: List<EvolutionNode>,
val renderData: RenderEvolutionData?,
) : TreeNode<EvolutionNode>
}
@@ -0,0 +1,64 @@
/*
* 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.layer
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.model.PlayerModel
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.entity.RenderLayerParent
import net.minecraft.client.renderer.entity.layers.RenderLayer
import net.minecraft.world.entity.HumanoidArm
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
import org.joml.Vector3f
class PlayerRecallBallRenderer<T : Player>(
renderLayerParent: RenderLayerParent<T, PlayerModel<T>>
) : RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
override fun render(
matrixStack: PoseStack,
buffer: MultiBufferSource,
packedLight: Int,
player: T,
limbSwing: Float,
limbSwingAmount: Float,
partialTicks: Float,
ageInTicks: Float,
netHeadYaw: Float,
headPitch: Float
) {
val anim = RecallArmAnimationTracker.get(player.uuid) ?: return
val mc = Minecraft.getInstance()
if (player === mc.player && mc.options.cameraType.isFirstPerson) return
matrixStack.pushPose()
getParentModel().translateToHand(HumanoidArm.RIGHT, matrixStack)
matrixStack.mulPose(Axis.XP.rotationDegrees(-90F))
matrixStack.mulPose(Axis.YP.rotationDegrees(180F))
matrixStack.translate(0.0625, 0.125, -0.625)
matrixStack.scale(0.54F, -0.54F, -0.54F)
matrixStack.translate(0.0, 0.5, 0.0)
matrixStack.mulPose(Axis.YP.rotationDegrees(180F))
RecallArmAnimationTracker.renderBall(anim, matrixStack, buffer, packedLight, partialTicks)
anim.ballState.locatorStates["beam"]?.let { beam ->
matrixStack.pushPose()
matrixStack.mulPose(beam.matrix)
val offset = matrixStack.last().pose().transformPosition(Vector3f(0F, 0.18F, -0.3F))
matrixStack.popPose()
anim.beamOrigin = mc.gameRenderer.mainCamera.position.add(Vec3(offset))
}
matrixStack.popPose()
}
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.client.render.layer
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.client.render.item.HeldItemRenderer
@@ -23,7 +24,6 @@ import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.isPokemonEntity
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import java.util.UUID
import net.minecraft.client.Minecraft
import net.minecraft.client.model.PlayerModel
@@ -33,11 +33,14 @@ import net.minecraft.client.renderer.entity.LivingEntityRenderer
import net.minecraft.client.renderer.entity.RenderLayerParent
import net.minecraft.client.renderer.entity.layers.RenderLayer
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ArmorItem
import net.minecraft.world.item.ItemStack
class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent<T, PlayerModel<T>>) :
@@ -165,16 +168,16 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
val width = shoulderData.form.hitbox.width
val heightOffset = -1.5 * scale
val widthOffset = width / 2 - 0.7
// If they're sneaking, the pokemon needs to rotate a little bit and push forward
// Shoulders move a bit when sneaking which is why the translation is necessary.
// Shoulder exact rotation according to testing (miasmus) is 0.4 radians, the -0.15 is eyeballed though.
if (livingEntity.isCrouching) {
matrixStack.mulPose(Axis.XP.rotation(0.4F))
matrixStack.translate(0F, 0F, -0.15F)
val chestItem = livingEntity.getItemBySlot(EquipmentSlot.CHEST)
val armorHeightOffset = if (chestItem.item is ArmorItem && !isArmorOffsetBlacklisted(chestItem)) {
ARMOR_HEIGHT_OFFSET
} else {
0F
}
parentModel.body.translateAndRotate(matrixStack)
matrixStack.translate(
if (pLeftShoulder) -widthOffset else widthOffset,
(if (livingEntity.isCrouching) heightOffset + 0.2 else heightOffset),
heightOffset - armorHeightOffset,
0.0
)
@@ -263,8 +266,14 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
companion object {
private const val ARMOR_HEIGHT_OFFSET = 1F / 16F
private val playerCache = hashMapOf<UUID, ShoulderCache>()
private fun isArmorOffsetBlacklisted(itemStack: ItemStack): Boolean {
val itemIdentifier = BuiltInRegistries.ITEM.getKey(itemStack.item)
return itemIdentifier in Cobblemon.config.shoulderMountArmorOffsetBlacklist
}
private fun extractUuid(shoulderNbt: CompoundTag): UUID {
if (!shoulderNbt.contains(DataKeys.SHOULDER_UUID)) {
return shoulderNbt.getCompound(DataKeys.POKEMON).getUUID(DataKeys.POKEMON_UUID)
@@ -545,11 +545,12 @@ abstract class PosableState : Schedulable {
primaryAnimation?.animation?.applyEffects(entity, this, previousSeconds, newSeconds)
currentModel?.let { model ->
val pose = currentPose?.let { model.poses[it] }
// Effects start playing from pose animations as long as the intensity is above 0.5. Pretty sloppy honestly.
pose?.animations
?.asSequence()
?.filter { shouldIdleRun(it, 0.5F) && it.condition(this) }
?.forEach { it.applyEffects(entity, this, previousSeconds, newSeconds) }
?.filter { it.condition(this) }
?.forEach {
it.applyEffects(entity, this, previousSeconds, newSeconds)
}
}
}
@@ -262,9 +262,9 @@ data class BedrockAnimation(
fun applyEffects(entity: Entity?, state: PosableState, previousSeconds: Float, newSeconds: Float) {
val effectCondition: (effectKeyframe: BedrockEffectKeyframe) -> Boolean =
if (previousSeconds > newSeconds) {
{ it.seconds >= previousSeconds || it.seconds <= newSeconds }
{ it.seconds >= previousSeconds || it.seconds < newSeconds }
} else {
{ it.seconds in previousSeconds..newSeconds }
{ it.seconds >= previousSeconds && it.seconds < newSeconds }
}
effects.filter(effectCondition).forEach { it.run(entity, state) }
@@ -1,104 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WaveAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WaveSegment
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation.Companion.X_AXIS
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation.Companion.Y_AXIS
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
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 net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class EkansModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("ekans")
private val body = getPart("body")
override val head = getPart("head")
private val tail = getPart("tail")
private val tail2 = getPart("tail2")
private val tail3 = getPart("tail3")
private val tail4 = getPart("tail4")
private val tail5 = getPart("tail5")
private val tail6 = getPart("tail6")
val tailSegment = WaveSegment(modelPart = tail, length = 9F)
val tail2Segment = WaveSegment(modelPart = tail2, length = 9F)
val tail3Segment = WaveSegment(modelPart = tail3, length = 9F)
val tail4Segment = WaveSegment(modelPart = tail4, length = 9F)
val tail5Segment = WaveSegment(modelPart = tail5, length = 10F)
val tail6Segment = WaveSegment(modelPart = tail6, length = 10F)
override var portraitScale = 1.7F
override var portraitTranslation = Vec3(-0.3, -0.45, 0.0)
override var profileScale = 0.7F
override var profileTranslation = Vec3(-0.05, 0.6, 0.0)
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("ekans", "cry") }
override fun registerPoses() {
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("ekans", "sleep"))
)
val blink = quirk { bedrockStateful("ekans", "blink") }
registerPose(
poseName = "normal",
poseTypes = STATIONARY_POSES + MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ekans", "ground_idle"),
WaveAnimation(
waveFunction = sineFunction(
period = 8F,
amplitude = 0.8F
),
basedOnLimbSwing = true,
oscillationsScalar = 5F,
head = head,
rotationAxis = Y_AXIS,
motionAxis = X_AXIS,
moveHead = false,
headLength = 16F,
segments = arrayOf(
tailSegment,
tail2Segment,
tail3Segment,
tail4Segment,
tail5Segment,
tail6Segment
)
)
)
)
registerPose(
poseName = "portrait",
poseTypes = UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(bedrock("ekans", "summary_idle"))
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("ekans", "faint")
}
@@ -1,63 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class GloomModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("gloom")
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(-0.0, -1.0, 0.0)
override var profileScale = 1.05F
override var profileTranslation = Vec3(0.0, 0.19, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("gloom", "cry") }
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
animations = arrayOf(
bedrock("gloom", "ground_idle")
)
)
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("gloom", "sleep"))
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
animations = arrayOf(
bedrock("gloom", "ground_walk")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("gloom", "faint")
}
@@ -1,66 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class OddishModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("oddish")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.0, -1.0, 0.0)
override var profileScale = 0.85F
override var profileTranslation = Vec3(0.0, 0.5, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("oddish", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("oddish", "blink")}
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("oddish", "ground_idle")
)
)
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("oddish", "sleep"))
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("oddish", "ground_walk")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("oddish", "faint")
}
@@ -1,75 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.STANDING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class PoliwagModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("poliwag")
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(0.0, -0.7, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.38, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var float: Pose
lateinit var swim: Pose
override val cryAnimation = CryProvider { bedrockStateful("poliwag", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("poliwag", "blink")}
standing = registerPose(
poseName = "standing",
poseTypes = STANDING_POSES + UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("poliwag", "ground_idle")
)
)
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("poliwag", "sleep"))
)
float = registerPose(
poseName = "float",
poseType = PoseType.FLOAT,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("poliwag", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseType = PoseType.SWIM,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("poliwag", "water_swim")
)
)
}
// override fun getFaintAnimation(
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("poliwag", "faint") else null
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
}
@@ -1,66 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class VileplumeModel(root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("vileplume")
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(-0.35, -0.8, 0.0)
override var profileScale = 0.8F
override var profileTranslation = Vec3(0.0, 0.53, 0.0)
lateinit var sleep: Pose
lateinit var standing: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("vileplume", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("vileplume", "blink")}
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("vileplume", "idle")
)
)
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("vileplume", "sleep"))
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("vileplume", "ground_walk")
)
)
}
override fun getFaintAnimation(state: PosableState) = bedrockStateful("vileplume", "faint")
}
@@ -1,95 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.SHOULDER_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class BellossomModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("bellossom")
override val head = getPart("head")
override var portraitScale = 1.8F
override var portraitTranslation = Vec3(0.0, -0.2, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.21, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
val shoulderOffset = 5
override fun registerPoses() {
val blink = quirk { bedrockStateful("bellossom", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("bellossom", "ground_idle"),
singleBoneLook()
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("bellossom", "ground_idle"),
bedrock("bellossom", "ground_walk"),
singleBoneLook()
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("bellossom", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("bellossom", "ground_idle")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("bellossom", "faint") else null
}
@@ -1,80 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
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.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class PolitoedModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("politoed")
override val head = getPart("head")
override val leftLeg = getPart("leftleg")
override val rightLeg = getPart("rightleg")
override var portraitScale = 2.4F
override var portraitTranslation = Vec3(-0.04, -0.55, 0.0)
override var profileScale = 1.1F
override var profileTranslation = Vec3(0.0, 0.1, 0.0)
lateinit var standing: Pose
lateinit var walking: Pose
lateinit var float: Pose
lateinit var swim: Pose
override fun registerPoses() {
standing = registerPose(
poseName = "standing",
poseTypes = UI_POSES + PoseType.STAND,
animations = arrayOf(
singleBoneLook(),
bedrock("politoed", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseType = PoseType.WALK,
animations = arrayOf(
singleBoneLook(),
bedrock("politoed", "ground_idle")
)
)
float = registerPose(
poseName = "float",
poseTypes = setOf(PoseType.FLOAT, PoseType.HOVER),
animations = arrayOf(
singleBoneLook(),
bedrock("politoed", "water_idle")
)
)
swim = registerPose(
poseName = "swim",
poseTypes = setOf(PoseType.SWIM, PoseType.FLY),
animations = arrayOf(
singleBoneLook(),
bedrock("politoed", "water_swim")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("politoed", "faint") else null
}
@@ -1,72 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType.Companion.MOVING_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.STATIONARY_POSES
import com.cobblemon.mod.common.entity.PoseType.Companion.UI_POSES
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SudowoodoModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("sudowoodo")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 1.9F
override var portraitTranslation = Vec3(-0.7, 1.6, 0.0)
override var profileScale = 0.5F
override var profileTranslation = Vec3(-0.1, 0.95, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("sudowoodo", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(yawMultiplier = 0F),
bedrock("sudowoodo", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(yawMultiplier = 0F),
bedrock("sudowoodo", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
//bedrock("sudowoodo", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("sudowoodo", "faint") else null
}
@@ -1,91 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import 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.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class ShroomishModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("shroomish")
override val head = getPart("torso")
override val leftLeg = getPart("foot_left")
override val rightLeg = getPart("foot_right")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(-0.1, -1.2, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.3, 0.0)
lateinit var standing: Pose
lateinit var battling: Pose
lateinit var sleeping: Pose
lateinit var walk: Pose
override val cryAnimation = CryProvider { bedrockStateful("shroomish", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("shroomish", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(pitchMultiplier = 0.5F),
bedrock("shroomish", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(pitchMultiplier = 0.5F),
bedrock("shroomish", "ground_walk")
)
)
battling = registerPose(
poseName = "battlestanding",
poseTypes = STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(pitchMultiplier = 0.5F),
bedrock("shroomish", "battle_idle")
)
)
sleeping = registerPose(
poseName = "sleeping",
poseType = PoseType.SLEEP,
transformTicks = 10,
animations = arrayOf(
bedrock("shroomish", "sleep")
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walk, battling, sleeping)) bedrockStateful("shroomish", "faint") else null
}
@@ -1,102 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen4
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.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
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.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class BonslyModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("bonsly")
override val head = getPart("torso")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 2.2F
override var portraitTranslation = Vec3(-0.2, -0.8, 0.0)
override var profileScale = 0.72F
override var profileTranslation = Vec3(0.0, 0.65, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var battleidle: Pose
lateinit var sleep: Pose
lateinit var battlesleep: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("bonsly", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = STATIONARY_POSES + UI_POSES,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("bonsly", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("bonsly", "ground_walk")
)
)
sleep = registerPose(
poseName = "sleep",
poseType = PoseType.SLEEP,
condition = { !it.isBattling },
animations = arrayOf(
bedrock("bonsly", "sleep_pot")
)
)
battlesleep = registerPose(
poseName = "battlesleep",
poseType = PoseType.SLEEP,
condition = { it.isBattling },
animations = arrayOf(
bedrock("bonsly", "sleep")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("bonsly", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk))
// bedrockStateful("bonsly", "faint")
// else null
}
@@ -231,13 +231,8 @@ object VaryingModelRepository {
inbuilt("paras", ::ParasModel)
inbuilt("mankey", ::MankeyModel)
inbuilt("primeape", ::PrimeapeModel)
inbuilt("oddish", ::OddishModel)
inbuilt("gloom", ::GloomModel)
inbuilt("vileplume", ::VileplumeModel)
inbuilt("bellossom", ::BellossomModel)
inbuilt("voltorb", ::VoltorbModel)
inbuilt("electrode", ::ElectrodeModel)
inbuilt("ekans", ::EkansModel)
inbuilt("machop", ::MachopModel)
inbuilt("machoke", ::MachokeModel)
inbuilt("machamp", ::MachampModel)
@@ -266,8 +261,6 @@ object VaryingModelRepository {
inbuilt("nidorino", ::NidorinoModel)
inbuilt("persian", ::PersianModel)
inbuilt("pinsir", ::PinsirModel)
inbuilt("poliwag", ::PoliwagModel)
inbuilt("politoed", ::PolitoedModel)
inbuilt("ponyta", ::PonytaModel)
inbuilt("psyduck", ::PsyduckModel)
inbuilt("rapidash", ::RapidashModel)
@@ -375,7 +368,6 @@ object VaryingModelRepository {
inbuilt("gliscor", ::GliscorModel)
inbuilt("poochyena", ::PoochyenaModel)
inbuilt("mightyena", ::MightyenaModel)
inbuilt("shroomish", ::ShroomishModel)
inbuilt("breloom", ::BreloomModel)
inbuilt("charcadet", ::CharcadetModel)
inbuilt("flittle", ::FlittleModel)
@@ -397,8 +389,6 @@ object VaryingModelRepository {
inbuilt("sirfetchd", ::SirfetchdModel)
inbuilt("duskull", ::DuskullModel)
inbuilt("dusclops", ::DusclopsModel)
inbuilt("bonsly", ::BonslyModel)
inbuilt("sudowoodo", ::SudowoodoModel)
inbuilt("cetoddle", ::CetoddleModel)
inbuilt("cetitan", ::CetitanModel)
inbuilt("aipom", ::AipomModel)
@@ -0,0 +1,31 @@
/*
* 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.player
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.MultiBufferSource
object FirstPersonRecallBallRenderer {
fun render(poseStack: PoseStack, buffer: MultiBufferSource, packedLight: Int, partialTicks: Float): Boolean {
val player = Minecraft.getInstance().player ?: return false
val anim = RecallArmAnimationTracker.get(player.uuid) ?: return false
val rise = RecallArmAnimationTracker.raiseFactor(player.uuid)
poseStack.pushPose()
poseStack.translate(0.45, -0.55 - 0.6 * (1.0 - rise), -0.6)
poseStack.scale(0.45F, -0.45F, -0.45F)
poseStack.mulPose(Axis.YP.rotationDegrees(180F))
poseStack.mulPose(Axis.XP.rotationDegrees(15F))
RecallArmAnimationTracker.renderBall(anim, poseStack, buffer, packedLight, partialTicks)
poseStack.popPose()
return true
}
}
@@ -0,0 +1,74 @@
/*
* 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.player
import com.cobblemon.mod.common.client.battle.ClientBallDisplay
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.pokeball.PokeBall
import com.mojang.blaze3d.vertex.PoseStack
import java.util.UUID
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
object RecallArmAnimationTracker {
private const val HOLD_SECONDS = 0.8
private const val EASE_SECONDS = 0.15
class RecallAnim(val ball: PokeBall, val startTimeMs: Long) {
val ballState = ClientBallDisplay(ball, emptySet())
var beamOrigin: Vec3? = null
}
private val activeRecalls = mutableMapOf<UUID, RecallAnim>()
private val ballContext = RenderContext().also { it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD) }
fun start(playerUuid: UUID, ball: PokeBall) {
activeRecalls[playerUuid] = RecallAnim(ball, System.currentTimeMillis())
}
fun get(playerUuid: UUID): RecallAnim? {
val anim = activeRecalls[playerUuid] ?: return null
if (secondsSince(anim) > HOLD_SECONDS) {
activeRecalls.remove(playerUuid)
return null
}
return anim
}
fun isRecalling(playerUuid: UUID) = get(playerUuid) != null
fun raiseFactor(playerUuid: UUID): Float {
val anim = get(playerUuid) ?: return 0F
val elapsed = secondsSince(anim)
val riseIn = Mth.clamp((elapsed / EASE_SECONDS).toFloat(), 0F, 1F)
val fallOut = Mth.clamp(((HOLD_SECONDS - elapsed) / EASE_SECONDS).toFloat(), 0F, 1F)
return minOf(riseIn, fallOut)
}
fun renderBall(anim: RecallAnim, poseStack: PoseStack, buffer: MultiBufferSource, packedLight: Int, partialTicks: Float) {
val state = anim.ballState
val model = VaryingModelRepository.getPoser(anim.ball.name, state)
val texture = VaryingModelRepository.getTexture(anim.ball.name, state)
state.updatePartialTicks(partialTicks)
model.context = ballContext
ballContext.put(RenderContext.ASPECTS, state.aspects)
ballContext.put(RenderContext.POSABLE_STATE, state)
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
val consumer = ItemRenderer.getFoilBufferDirect(buffer, RenderType.entityCutout(texture), false, false)
model.render(ballContext, poseStack, consumer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
model.resetLayerContext()
}
private fun secondsSince(anim: RecallAnim) = (System.currentTimeMillis() - anim.startTimeMs) / 1000.0
}
@@ -26,6 +26,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PosableP
import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscModelRepository
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
import com.cobblemon.mod.common.client.render.pokeball.PokeBallPosableState
import com.cobblemon.mod.common.client.render.renderBeaconBeam
import com.cobblemon.mod.common.client.settings.ServerSettings
@@ -60,6 +61,7 @@ import net.minecraft.network.chat.Style
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
import org.joml.*
import kotlin.math.*
@@ -316,8 +318,11 @@ class PokemonRenderer(
fun renderBeam(matrixStack: PoseStack, partialTicks: Float, entity: PokemonEntity, beamTarget: Entity, buffer: MultiBufferSource, offset: Vec3) {
val clientDelegate = entity.delegate as PokemonClientDelegate
val pokemonPosition = entity.position().add(0.0, entity.bbHeight / 2.0 * clientDelegate.activeSendoutScale.toDouble(), 0.0)
var beamSourcePosition = if (beamTarget is EmptyPokeBallEntity) {
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]?.getOrigin() ?: beamTarget.position()
val recallBallOrigin = (beamTarget as? Player)?.let { RecallArmAnimationTracker.get(it.uuid)?.beamOrigin }
var beamSourcePosition = if (recallBallOrigin != null) {
recallBallOrigin
} else if (beamTarget is EmptyPokeBallEntity) {
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]?.transformPosition(Vec3(0.0, 0.2, 0.45)) ?: beamTarget.position()
} else {
if (beamTarget.uuid == Minecraft.getInstance().player?.uuid) {
val lookVec = beamTarget.lookAngle.yRot((PI / 2).toFloat()).multiply(1.0, 0.0, 1.0).normalize()
@@ -216,6 +216,9 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Pokemon, lang = "display_entity_labels_when_crouching_only", CLIENT)
var displayEntityLabelsWhenCrouchingOnly = false
@CobblemonConfigField(Category.Pokemon, lang = "shoulder_mount_armor_offset_blacklist", CLIENT)
var shoulderMountArmorOffsetBlacklist = mutableSetOf<ResourceLocation>()
@CobblemonConfigField(Category.Spawning, lang = "shiny_rate", SERVER)
var shinyRate = 8192F
@@ -1483,19 +1483,31 @@ open class PokemonEntity(
// Evolution item logic
if (pokemon.getOwnerPlayer() == player) {
fun evolutionUnlocked(): Boolean {
stack.consume(1, player)
this.level().playSoundServer(
position = this.position(),
sound = CobblemonSounds.ITEM_USE,
volume = 1F,
pitch = 1F
)
return true
}
val context = ItemInteractionEvolution.ItemInteractionContext(stack, player.level())
pokemon.lockedEvolutions
.filterIsInstance<ItemInteractionEvolution>()
.forEach { evolution ->
if (evolution.attemptEvolution(pokemon, context)) {
stack.consume(1, player)
this.level().playSoundServer(
position = this.position(),
sound = CobblemonSounds.ITEM_USE,
volume = 1F,
pitch = 1F
)
return true
val lockedItemEvolutions = pokemon.lockedEvolutions.filterIsInstance<ItemInteractionEvolution>()
// forced evolutions > check those first and do ONLY one if there's multiple
lockedItemEvolutions.filter { !it.optional }.forEach {
if (it.attemptEvolution(pokemon, context)) {
return evolutionUnlocked()
}
}
// optional evolutions > unlock all with single item use
lockedItemEvolutions.filter { it.optional }
// we unlock all evolutions that depend on this single item
.map { evolution -> return@map evolution.attemptEvolution(pokemon, context) }
.let {
if (it.contains(true)) { // if any of the evolutions were unlocked, we take the item
return evolutionUnlocked()
}
}
}
@@ -0,0 +1,100 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.net.messages.client.data
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.pokemon.evolution.PreEvolution
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.writeString
import com.google.gson.reflect.TypeToken
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
/**
* Carries the evolutions/preEvolution of every [Species] (and any [FormData] overrides), sent right after
* [SpeciesRegistrySyncPacket] so that every species is already registered by the time this is decoded. This avoids
* the cross-species lookup ordering hazards that come with resolving evolutions during the species sync itself.
*/
class SpeciesEvolutionSyncPacket(entries: Collection<SpeciesEvolutionEntry>) : DataRegistrySyncPacket<SpeciesEvolutionEntry, SpeciesEvolutionSyncPacket>(entries) {
override val id = ID
override fun encodeEntry(buffer: RegistryFriendlyByteBuf, entry: SpeciesEvolutionEntry) {
try {
buffer.writeIdentifier(entry.speciesIdentifier)
buffer.writeString(PokemonSpecies.gson.toJson(entry.evolutions, EVOLUTION_SET_TYPE))
buffer.writeNullable(entry.preEvolution) { _, preEvolution -> buffer.writeString(PokemonSpecies.gson.toJson(preEvolution, PreEvolution::class.java)) }
buffer.writeCollection(entry.formOverrides) { _, override ->
buffer.writeString(override.formName)
buffer.writeNullable(override.evolutions) { _, evolutions -> buffer.writeString(PokemonSpecies.gson.toJson(evolutions, EVOLUTION_SET_TYPE)) }
buffer.writeNullable(override.preEvolution) { _, preEvolution -> buffer.writeString(PokemonSpecies.gson.toJson(preEvolution, PreEvolution::class.java)) }
}
} catch (e: Exception) {
Cobblemon.LOGGER.error("Caught exception encoding evolution data for species {}", entry.speciesIdentifier, e)
}
}
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): SpeciesEvolutionEntry? {
val identifier = buffer.readIdentifier()
return try {
val evolutions: MutableSet<Evolution> = PokemonSpecies.gson.fromJson(buffer.readString(), EVOLUTION_SET_TYPE)
val preEvolution = buffer.readNullable { _ -> PokemonSpecies.gson.fromJson(buffer.readString(), PreEvolution::class.java) }
val formOverrides = buffer.readList { _ ->
val formName = buffer.readString()
val formEvolutions = buffer.readNullable { _ -> PokemonSpecies.gson.fromJson<MutableSet<Evolution>>(buffer.readString(), EVOLUTION_SET_TYPE) }
val formPreEvolution = buffer.readNullable { _ -> PokemonSpecies.gson.fromJson(buffer.readString(), PreEvolution::class.java) }
FormEvolutionOverride(formName, formEvolutions, formPreEvolution)
}
SpeciesEvolutionEntry(identifier, evolutions, preEvolution, formOverrides)
} catch (e: Exception) {
Cobblemon.LOGGER.error("Caught exception decoding evolution data for species {}", identifier, e)
null
}
}
override fun synchronizeDecoded(entries: Collection<SpeciesEvolutionEntry>) {
entries.forEach { entry ->
val species = PokemonSpecies.getByIdentifier(entry.speciesIdentifier)
if (species == null) {
Cobblemon.LOGGER.error("Received evolution data for unknown species {}", entry.speciesIdentifier)
return@forEach
}
species.applyEvolutionData(entry.evolutions, entry.preEvolution)
entry.formOverrides.forEach { override ->
species.getFormByName(override.formName).applyEvolutionData(override.evolutions, override.preEvolution)
}
}
}
companion object {
val ID = cobblemonResource("species_evolution_sync")
private val EVOLUTION_SET_TYPE = TypeToken.getParameterized(MutableSet::class.java, Evolution::class.java).type
fun decode(buffer: RegistryFriendlyByteBuf): SpeciesEvolutionSyncPacket = SpeciesEvolutionSyncPacket(emptyList()).apply { decodeBuffer(buffer) }
}
}
class SpeciesEvolutionEntry(
val speciesIdentifier: ResourceLocation,
val evolutions: MutableSet<Evolution>,
val preEvolution: PreEvolution?,
val formOverrides: List<FormEvolutionOverride>
)
class FormEvolutionOverride(
val formName: String,
val evolutions: MutableSet<Evolution>?,
val preEvolution: PreEvolution?
)
@@ -76,7 +76,7 @@ class FormData(
@SerializedName("moves")
private var _moves: Learnset? = null,
@SerializedName("evolutions")
private val _evolutions: MutableSet<Evolution>? = null,
private var _evolutions: MutableSet<Evolution>? = null,
@SerializedName("abilities")
private var _abilities: AbilityPool? = null,
@SerializedName("drops")
@@ -84,7 +84,7 @@ class FormData(
@SerializedName("pokedex")
private var _pokedex: MutableList<String>? = null,
@SerializedName("preEvolution")
private val _preEvolution: PreEvolution? = null,
private var _preEvolution: PreEvolution? = null,
private var standingEyeHeight: Float? = null,
private var swimmingEyeHeight: Float? = null,
private var flyingEyeHeight: Float? = null,
@@ -210,6 +210,14 @@ class FormData(
val evolutions: MutableSet<Evolution>
get() = _evolutions ?: mutableSetOf()
/** The evolutions explicitly set on this form, as opposed to [evolutions] which falls back to an empty set. Used to tell whether this form overrides the species' evolutions when syncing. */
internal val ownEvolutions: MutableSet<Evolution>?
get() = this._evolutions
/** The preEvolution explicitly set on this form, as opposed to [preEvolution] which falls back to the species'. Used to tell whether this form overrides the species' preEvolution when syncing. */
internal val ownPreEvolution: PreEvolution?
get() = this._preEvolution
val battleTheme: ResourceLocation
get() = _battleTheme ?: species.battleTheme
@@ -261,15 +269,24 @@ class FormData(
this.species = species
this.behaviour.parent = species.behaviour
Cobblemon.statProvider.provide(this)
// These properties are lazy, these need all species to be reloaded but SpeciesAdditions is what will eventually trigger this after all species have been loaded
this.preEvolution?.species
this.preEvolution?.form
this.evolutions.size
this._lightingData?.let { this._lightingData = it.copy(lightLevel = it.lightLevel.coerceIn(0, 15)) }
behaviour.herd.initialize()
return this
}
/**
* Applies decoded evolution data onto this form, received separately via [com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionSyncPacket]
* after every species has already been registered.
*/
internal fun applyEvolutionData(evolutions: MutableSet<Evolution>?, preEvolution: PreEvolution?) {
this._evolutions = evolutions
this._preEvolution = preEvolution
// These properties are lazy, force resolution now that every species is guaranteed to be registered
this.preEvolution?.species
this.preEvolution?.form
this.evolutions.size
}
internal fun resolveEvolutionMoves() {
this.evolutions.forEach { evolution ->
if (evolution.learnableMoves.isNotEmpty() && evolution.result.species != null) {
@@ -181,11 +181,20 @@ class Species : ShowdownIdentifiable {
this.forms.add(0, this.standardForm)
}
this.lightingData?.let { this.lightingData = it.copy(lightLevel = it.lightLevel.coerceIn(0, 15)) }
// These properties are lazy, these need all species to be reloaded but SpeciesAdditions is what will eventually trigger this after all species have been loaded
behaviour.herd.initialize()
}
/**
* Applies decoded evolution data onto this species, received separately via [com.cobblemon.mod.common.net.messages.client.data.SpeciesEvolutionSyncPacket]
* after every species has already been registered.
*/
internal fun applyEvolutionData(evolutions: MutableSet<Evolution>, preEvolution: PreEvolution?) {
// Mutate in place rather than reassign: standardForm may have already captured this.evolutions by reference.
this.evolutions.clear()
this.evolutions.addAll(evolutions)
this.preEvolution = preEvolution
this.preEvolution?.species
this.preEvolution?.form
this.evolutions.size
behaviour.herd.initialize()
}
// Ran after initialize due to us creating a Pokémon here which requires all the properties in #initialize to be present for both this and the results, this is the easiest way to quickly resolve species + form
@@ -36,6 +36,8 @@ import kotlin.reflect.KClass
object CobblemonRequirementAdapter : RequirementAdapter {
private const val VARIANT = "variant"
private const val POKEDEX_ICON = "pokedexIcon"
private const val POKEDEX_TOOLTIP = "pokedexTooltip"
private val types = HashBiMap.create<String, KClass<out Requirement>>()
@@ -75,7 +77,7 @@ object CobblemonRequirementAdapter : RequirementAdapter {
GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter)
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter())
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
@@ -90,15 +92,26 @@ object CobblemonRequirementAdapter : RequirementAdapter {
}
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Requirement {
val variant = json.asJsonObject.get(VARIANT).asString.lowercase()
val obj = json.asJsonObject
val variant = obj.get(VARIANT).asString.lowercase()
val type = getRequirementType(variant)
return context.deserialize(json, type.java)
val requirement = context.deserialize<Requirement>(json, type.java)
obj.get(POKEDEX_ICON)?.takeIf { !it.isJsonNull }
?.let { context.deserialize<ResourceLocation>(it, ResourceLocation::class.java) }
?.let { Requirement.pokedexIconOverrides[requirement] = it }
obj.get(POKEDEX_TOOLTIP)?.takeIf { !it.isJsonNull }?.asString
?.let { Requirement.pokedexTooltipOverrides[requirement] = it }
return requirement
}
override fun serialize(requirement: Requirement, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
val json = context.serialize(requirement, requirement::class.java).asJsonObject
val variant = getVariant(requirement)
json.addProperty(VARIANT, variant)
Requirement.pokedexIconOverrides[requirement]?.let { json.add(POKEDEX_ICON, context.serialize(it, ResourceLocation::class.java)) }
Requirement.pokedexTooltipOverrides[requirement]?.let { json.addProperty(POKEDEX_TOOLTIP, it) }
return json
}
@@ -25,12 +25,20 @@ internal class CobblemonLazyPreEvolution(private val rawData: String) : PreEvolu
this.properties.species?.asIdentifierDefaultingNamespace()?.let { PokemonSpecies.getByIdentifier(it) } ?: throw IllegalArgumentException("A PreEvolution needs a valid species")
}
private val lazyForm: FormData by lazy {
this.properties.form?.let { formId -> this.species.forms.firstOrNull { it.formOnlyShowdownId().equals(formId, true) } } ?: this.species.standardForm
private fun computeForm(extraAspects: Set<String>): FormData {
val properties = this.properties
return properties.form?.let { formId -> this.species.forms.firstOrNull { it.formOnlyShowdownId().equals(formId, true) } }
?: this.species.getForm(properties.aspects + this.rawData.split(" ").map { it.lowercase() }.toSet() + extraAspects)
}
private val lazyForm: FormData by lazy { computeForm(emptySet()) }
override val species: Species
get() = this.lazySpecies
override val form: FormData
get() = this.lazyForm
override fun resolveForm(extraAspects: Set<String>): FormData {
return if (extraAspects.isEmpty()) this.form else computeForm(extraAspects)
}
}
@@ -12,10 +12,12 @@ import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
import net.minecraft.world.phys.AABB
object BoxAdapter : JsonDeserializer<AABB> {
object BoxAdapter : JsonDeserializer<AABB>, JsonSerializer<AABB> {
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): AABB {
json as JsonObject
return AABB(
@@ -27,4 +29,15 @@ object BoxAdapter : JsonDeserializer<AABB> {
json.get("maxZ")?.asDouble ?: 9999999.0
)
}
override fun serialize(src: AABB, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
val json = JsonObject()
json.addProperty("minX", src.minX)
json.addProperty("minY", src.minY)
json.addProperty("minZ", src.minZ)
json.addProperty("maxX", src.maxX)
json.addProperty("maxY", src.maxY)
json.addProperty("maxZ", src.maxZ)
return json
}
}
@@ -13,6 +13,8 @@ import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
/**
@@ -22,7 +24,7 @@ import java.lang.reflect.Type
* @author Hiroku
* @since July 24th, 2022
*/
object DropEntryAdapter : JsonDeserializer<DropEntry> {
object DropEntryAdapter : JsonDeserializer<DropEntry>, JsonSerializer<DropEntry> {
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): DropEntry {
json as JsonObject
val entryClass = json.get("type")?.asString
@@ -30,4 +32,12 @@ object DropEntryAdapter : JsonDeserializer<DropEntry> {
?: DropEntry.defaultType
return ctx.deserialize(json, entryClass)
}
override fun serialize(src: DropEntry, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
val json = ctx.serialize(src, src::class.java).asJsonObject
val name = DropEntry.entryTypes.entries.find { it.value == src::class.java }?.key
?: throw IllegalArgumentException("Cannot resolve drop entry type for ${src::class.qualifiedName}")
json.addProperty("type", name)
return json
}
}
@@ -10,13 +10,21 @@ package com.cobblemon.mod.common.util.adapters
import com.bedrockk.molang.Expression
import com.bedrockk.molang.MoLang
import com.cobblemon.mod.common.util.getString
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
object ExpressionAdapter : JsonDeserializer<Expression> {
object ExpressionAdapter : JsonDeserializer<Expression>, JsonSerializer<Expression> {
override fun deserialize(json: JsonElement, typeOfT: Type, ctx: JsonDeserializationContext): Expression {
return MoLang.createParser(json.asString).parseExpression()
}
override fun serialize(src: Expression, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
return JsonPrimitive(src.getString())
}
}
@@ -13,6 +13,9 @@ import com.cobblemon.mod.common.util.asExpressionLike
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
/**
@@ -22,7 +25,7 @@ import java.lang.reflect.Type
* @author Hiroku
* @since October 22nd, 2023
*/
object ExpressionLikeAdapter : JsonDeserializer<ExpressionLike> {
object ExpressionLikeAdapter : JsonDeserializer<ExpressionLike>, JsonSerializer<ExpressionLike> {
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): ExpressionLike {
return if (json.isJsonPrimitive) {
json.asString.asExpressionLike()
@@ -32,4 +35,8 @@ object ExpressionLikeAdapter : JsonDeserializer<ExpressionLike> {
throw IllegalArgumentException("Invalid expression JSON: $json")
}
}
override fun serialize(src: ExpressionLike, typeOfSrc: Type, ctx: JsonSerializationContext): JsonElement {
return JsonPrimitive(src.getString())
}
}
@@ -5,396 +5,722 @@
"loop": true,
"bones": {
"body": {
"rotation": [-5, 0, 0],
"position": [0, "(math.sin(q.anim_time*90*2+90)*1-1)*0.15", 0]
"position": [0, 0, -8]
},
"head": {
"rotation": ["5-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", 0, 0]
"rotation": ["72.5-math.sin(q.anim_time*90*2-180)*1.25", -2.5, -10],
"position": [0, 0, 0]
},
"neck2": {
"rotation": ["7.5-math.sin(q.anim_time*90*2-90)", -5, -2.5],
"position": [0, -0.4, 0]
},
"tail": {
"rotation": ["-2.5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0]
"rotation": [0, 52.5, 0]
},
"tail2": {
"rotation": ["5+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0]
"rotation": [0, -45, 0],
"position": [0.7, 0, -0.55]
},
"tail3": {
"rotation": [2.5, 0, 0]
"rotation": [0, -70, 0],
"position": [1.6, 0, -1.2]
},
"jaw": {
"rotation": ["5-(math.sin(q.anim_time*90*2+90)*1-0.5)*1", 0, 0]
"tail4": {
"rotation": [0, -55, 0],
"position": [0.95, 0, -0.8]
},
"tail5": {
"rotation": [0, "57.5-math.sin(q.anim_time*90*2-120)*0.75", 0],
"position": [-1, 0, -0.75]
},
"tail6": {
"rotation": [0, "57.5-math.sin(q.anim_time*90*2-180)", 0],
"position": [-0.7, 0, -0.8]
},
"tail7": {
"rotation": ["5-math.sin(q.anim_time*90-240)*2", "45-math.sin(q.anim_time*90*2-240)*1.25", 0],
"position": [-0.3, 0, -0.1]
},
"tail8": {
"rotation": ["12.5-math.sin(q.anim_time*90-300)*2.5", "37.5-math.sin(q.anim_time*90*2-300)*1.5", 7.5],
"position": [0, 0.25, 0]
},
"tail9": {
"rotation": ["22.5-math.sin(q.anim_time*90-360)*3", "40-math.sin(q.anim_time*90*2-360)*2", 5]
},
"tail_rattle": {
"rotation": ["22.5-math.sin(q.anim_time*90-30)*4", "-math.sin(q.anim_time*90*2-10)*4", 0]
},
"tail_rattle2": {
"rotation": ["6.4956-math.sin(q.anim_time*90-70)*6", "-math.sin(q.anim_time*90*2-70)*6", 0]
},
"coiled_body": {
"scale": 0
},
"neck": {
"rotation": ["-70-math.sin(q.anim_time*90*2)*0.5", 17.5, -2.5],
"position": [0.2, -0.4, -0.3]
}
}
},
"animation.ekans.summary_idle": {
"animation.ekans.battle_idle": {
"loop": true,
"bones": {
"ekans": {
"position": [0, -0.5, 0]
},
"body": {
"position": [0, 9, 12]
"position": [0, 6, 0]
},
"head": {
"rotation": ["7.5-math.sin(q.anim_time*90*2-45)*0.5", 0, 0]
"rotation": ["35-math.sin(q.anim_time*90*3-180)*2", -11.5, -8.5],
"position": [0.75, 0, -1.1]
},
"neck2": {
"rotation": ["42.5-math.sin(q.anim_time*90*3-60)*1.25", -7.5, -5],
"position": [0, -0.3, 0]
},
"tail": {
"rotation": [-37.5, 0, 0]
"rotation": [90, -32, -272.5],
"position": [-3, -0.5, 1],
"scale": 0
},
"tail2": {
"rotation": [91.18096, -64.66751, -112.80195]
"rotation": [-176.62147, -67.38079, 169.49348]
},
"tail3": {
"rotation": [56.22229, -69.76781, -69.82589]
"rotation": [160, -85, -180]
},
"tail8": {
"rotation": [77.80887, 32.27264, 55.07287],
"position": [-1, -1.1, -2]
},
"tail9": {
"rotation": [18.4215, -23.19625, -12.13932]
},
"tail4": {
"rotation": [0, -65, 0]
"rotation": [87.73292, -75.69796, -92.26708]
},
"tail5": {
"rotation": [0, "-52.5+math.sin(q.anim_time*90*2-120)*1", 0]
"rotation": [-2.5, -87.5, 0]
},
"tail6": {
"rotation": ["8.5+(math.sin(q.anim_time*90*2+90)*1-1)*0.5", "-57.5+math.sin(q.anim_time*90*2-90)*0.5", "-math.sin(q.anim_time*90*2)*0.25"]
"rotation": [0, -62.5, 0]
},
"rattle": {
"rotation": [40, "-10-math.sin(q.anim_time*90*32)*2", 0]
},
"rattle2": {
"rotation": [12.5, "-math.sin(q.anim_time*90*32-30)*2", 0]
},
"rattle3": {
"rotation": [12.5, "-math.sin(q.anim_time*90*32-30*2)*2", 0]
},
"rattle4": {
"rotation": [5, "-math.sin(q.anim_time*90*32-30*3)*2", 0]
},
"rattle5": {
"rotation": [5, "-math.sin(q.anim_time*90*32-30*4)*2", 0]
"tail7": {
"rotation": [-1.41397, -67.50536, -1.13438]
},
"jaw": {
"rotation": ["5-math.sin(q.anim_time*90*2-45)*1", 0, 0]
"rotation": ["12.5-math.sin(q.anim_time*90*3-150)*1.5", 0, 0],
"position": [0, -0.55, 0.25]
},
"coiled_body": {
"rotation": [0, "30-math.sin(q.anim_time*90*3-120)*0.25", 0],
"position": [0, 0, -5]
},
"coiled_body_top": {
"rotation": ["-math.sin(q.anim_time*90*3-60)*0.5", "math.sin(q.anim_time*90*3-60)*0.25", "-2.5-math.sin(q.anim_time*90*1.5+45)*0.5"]
},
"tail_rattle2": {
"rotation": [9.09308, -27.20461, 4.52273]
},
"head_ai": {
"rotation": [0, -5, 5]
},
"neck": {
"rotation": ["-67.5-math.sin(q.anim_time*90*3)", 27.5, "-6.5+math.sin(q.anim_time*90*1.5-90)*1.5"],
"position": [-2, 0, 1.5]
},
"coiled_tail": {
"rotation": ["25+math.sin(q.anim_time*90*1.5-30)*1.5", "-10+math.sin(q.anim_time*90*12-30)*0.75", 7.5]
},
"coiled_tail2": {
"rotation": ["27.5+math.sin(q.anim_time*90*1.5-60)*2", "-22.5+math.sin(q.anim_time*90*12-90)*2.25", 0]
},
"coiled_tail_rattle": {
"rotation": ["27.5+math.sin(q.anim_time*90*1.5-90)*3", "-12.5+math.sin(q.anim_time*90*24-150)*3", -2.5]
},
"coiled_tail_rattle2": {
"rotation": ["math.sin(q.anim_time*90*1.5-120)*3", "math.sin(q.anim_time*90*24-210)*6", 0]
},
"coiled_tail_rattle3": {
"rotation": ["math.sin(q.anim_time*90*1.5-150)*4", "math.sin(q.anim_time*90*24-270)*8", 0]
}
}
},
"animation.ekans.faint": {
"animation_length": 3,
"animation.ekans.ground_walk": {
"loop": true,
"bones": {
"body": {
"rotation": {
"0.0": [-32.5, 0, 0],
"0.05": [-42.5, 0, 0],
"0.2": [-65.02089, -1.05627, 2.26603],
"0.35": [-90, 0, 5],
"0.7": [-97.10022, 0, 5],
"1.0": [-102.1, 0, 5],
"1.1": [-95.59, -0.25, 4.03],
"1.3": [-8.5468, -1.25885, 0.16067],
"1.45": [-7.0468, -1.25885, 0.16067]
},
"position": {
"0.0": [0, "-4.4+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -1.6],
"0.05": [0, "-2.6+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -1.1],
"0.2": [0, "-3.6+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -2.7],
"0.3": [0, -4.83, -6.77],
"0.35": [0, "-4.9+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -8.8],
"0.7": [0, "-3.8+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -9.6],
"1.0": [0, "-3.4+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -10.2],
"1.1": [0, -4, -9.26],
"1.15": [0, "-5.6+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -5.73],
"1.25": [0, -4.59, -2.31],
"1.3": [0, "-2.45+(math.sin(q.anim_time*90*2+90)*1-1)*0.15", -0.7],
"1.45": [0, "-2.25+(math.sin(q.anim_time*90*2+90)*1-1)*0.05", -0.7]
}
"position": ["-math.sin(q.anim_time*90*3-60)*3", 0, -13]
},
"head": {
"rotation": {
"0.0": ["65-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", 0, 0],
"0.1": ["75-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", 0, 0],
"0.25": ["15.1228-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", 7.24656, 1.9384],
"0.4": ["-21.1683-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", 18.759, -7.06381],
"0.5": [-22.32668, 16.91862, -6.3202],
"0.9": ["-25.7603-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -13.61143, 6.36351],
"0.95": ["-26.04-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -15.87438, 7.46234],
"1.0": ["-26.04-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -15.87, 7.46],
"1.15": ["-51.04-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -15.87, 7.46],
"1.3": ["-51.04-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -15.87, 7.46],
"1.35": ["19.4806-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -11.956, -14.52],
"1.4": ["10.9676-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", -19.92467, 13.66498],
"1.45": ["20.3399-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.1", -14.86025, -1.19814]
},
"position": {
"1.3": [0, 0, 0],
"1.45": [0, 0.5, 0]
}
"rotation": [55, "math.sin(q.anim_time*90*3+270)*16", "math.sin(q.anim_time*90*3+240)*10"]
},
"neck2": {
"rotation": [-25, "math.sin(q.anim_time*90*3+180)*16", 0]
},
"tail": {
"rotation": {
"0.0": ["5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.05": ["-7.5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.2": ["-7.5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.35": ["7.5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"1.0": ["7.5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"1.15": ["7.5-(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"1.35": ["7.5-(math.sin(q.anim_time*90*2+90)*1-1)*0.25", 0, 0]
}
"rotation": [0, "math.sin(q.anim_time*90*3)*14", 0]
},
"tail2": {
"rotation": {
"0.0": ["20+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.05": ["32.5+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.2": ["45+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.35": ["55+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"0.95": ["60+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"1.0": ["60+(math.sin(q.anim_time*90*2+90)*1-1)*1", 0, 0],
"1.1": [50.55, 0, 0],
"1.3": ["(math.sin(q.anim_time*90*2+90)*1-1)*0.5", 0, 0]
}
"rotation": [0, "math.sin(q.anim_time*90*3-60)*8", 0]
},
"tail3": {
"rotation": [0, "math.sin(q.anim_time*90*3-120)*12", 0]
},
"tail4": {
"rotation": [0, "math.sin(q.anim_time*90*3-180)*16", 0]
},
"tail5": {
"rotation": [0, "math.sin(q.anim_time*90*3-210)*16", 0]
},
"tail6": {
"rotation": [0, "math.sin(q.anim_time*90*3-240)*14", 0]
},
"tail7": {
"rotation": [0, "math.sin(q.anim_time*90*3-270)*12", 0]
},
"tail8": {
"rotation": [0, "math.sin(q.anim_time*90*3-300)*14", 0]
},
"tail9": {
"rotation": [0, "math.sin(q.anim_time*90*3-330)*18", 0]
},
"tail_rattle": {
"rotation": [0, "math.sin(q.anim_time*90*3-10)*20", 0]
},
"coiled_body": {
"scale": 0
},
"neck": {
"rotation": [-30, "math.sin(q.anim_time*90*3+60)*20", 0],
"position": [0, 0, 0.25]
}
}
},
"animation.ekans.ground_run": {
"loop": true,
"bones": {
"body": {
"position": ["-math.sin(q.anim_time*90*5-60)*3", 0, -13]
},
"head": {
"rotation": [0, "math.sin(q.anim_time*90*5+270)*18", 0]
},
"neck2": {
"rotation": [0, "math.sin(q.anim_time*90*5+180)*16", 0]
},
"tail": {
"rotation": [0, "math.sin(q.anim_time*90*5)*16", 0]
},
"tail2": {
"rotation": [0, "math.sin(q.anim_time*90*5-60)*12", 0]
},
"tail3": {
"rotation": [0, "math.sin(q.anim_time*90*5-120)*14", 0]
},
"tail4": {
"rotation": [0, "math.sin(q.anim_time*90*5-180)*16", 0]
},
"tail5": {
"rotation": [0, "math.sin(q.anim_time*90*5-210)*18", 0]
},
"tail6": {
"rotation": [0, "math.sin(q.anim_time*90*5-240)*18", 0]
},
"tail7": {
"rotation": [0, "math.sin(q.anim_time*90*5-270)*16", 0]
},
"tail8": {
"rotation": [0, "math.sin(q.anim_time*90*5-300)*14", 0]
},
"tail9": {
"rotation": [0, "math.sin(q.anim_time*90*5-330)*12", 0]
},
"tail_rattle": {
"rotation": [0, "math.sin(q.anim_time*90*5-10)*18", 0]
},
"coiled_body": {
"scale": 0
},
"neck": {
"rotation": [0, "math.sin(q.anim_time*90*5+60)*18", 0]
}
}
},
"animation.ekans.snake_ground_walk": {
"loop": true,
"bones": {
"body": {
"position": ["-q.r.yaw_change(3)*1", 0, 0]
},
"head": {
"rotation": [0, 0, "q.r.yaw_change(0)*5"],
"position": ["-q.r.yaw_change(0)*-0.2", "q.r.yaw_change(0)*0.25", 0]
},
"neck2": {
"rotation": [0, "-q.r.yaw_change(0)*-15", 0],
"position": ["-q.r.yaw_change(0)*0.3", 0, 0]
},
"tail": {
"rotation": [0, "-q.r.yaw_change(3)*-7.5", 0],
"position": ["-q.r.yaw_change(3)*-0.15", 0, "math.abs(q.r.yaw_change(3)*0.5)"]
},
"tail2": {
"rotation": [0, "-q.r.yaw_change(5)*5", 0]
},
"tail3": {
"rotation": [0, "-q.r.yaw_change(10)*2.5", 0]
},
"tail4": {
"rotation": [0, "-q.r.yaw_change(12)*7.5", 0]
},
"tail5": {
"rotation": [0, "-q.r.yaw_change(15)*7.5", 0]
},
"tail6": {
"rotation": [0, "-q.r.yaw_change(17)*10", 0]
},
"tail7": {
"rotation": [0, "-q.r.yaw_change(20)*7.5", 0]
},
"tail8": {
"rotation": [0, "-q.r.yaw_change(22)*5", 0]
},
"tail9": {
"rotation": [0, "-q.r.yaw_change(24)*5", 0]
},
"tail_rattle": {
"rotation": [0, "-q.r.yaw_change(26)*2.5", 0]
},
"neck": {
"rotation": [0, "-q.r.yaw_change(0)*-25", 0],
"position": ["-q.r.yaw_change(0)*0.25", 0, 0]
}
}
},
"animation.ekans.snake_ground_run": {
"loop": true,
"bones": {
"body": {
"position": ["-q.r.yaw_change(3)*2", 0, 0]
},
"head": {
"rotation": [0, "-q.r.yaw_change(0)*-10", 0],
"position": ["-q.r.yaw_change(0)*-0.2", "q.r.yaw_change(0)*0.25", 0]
},
"neck2": {
"rotation": [0, "-q.r.yaw_change(0)*-15", 0],
"position": ["-q.r.yaw_change(0)*0.25", 0, 0]
},
"tail": {
"rotation": [0, "-q.r.yaw_change(3)*-10", 0],
"position": ["-q.r.yaw_change(3)*-0.15", 0, 0]
},
"tail2": {
"rotation": [0, "-q.r.yaw_change(5)*5", 0]
},
"tail3": {
"rotation": [0, "-q.r.yaw_change(10)*5", 0]
},
"tail4": {
"rotation": [0, "-q.r.yaw_change(12)*7.5", 0]
},
"tail5": {
"rotation": [0, "-q.r.yaw_change(15)*10", 0]
},
"tail6": {
"rotation": [0, "-q.r.yaw_change(17)*7.5", 0]
},
"tail7": {
"rotation": [0, "-q.r.yaw_change(20)*10", 0]
},
"tail8": {
"rotation": [0, "-q.r.yaw_change(22)*5", 0]
},
"tail9": {
"rotation": [0, "-q.r.yaw_change(24)*5", 0]
},
"tail_rattle": {
"rotation": [0, "-q.r.yaw_change(26)*2.5", 0]
},
"neck": {
"rotation": [0, "-q.r.yaw_change(0)*-35", 0]
}
}
},
"animation.ekans.cry": {
"animation_length": 1.5,
"bones": {
"head": {
"rotation": {
"0.0": [7.5, 0, 0],
"0.05": [17.5, 0, 0],
"0.2": [27.5, 0, 0],
"0.7": [35, 0, 0],
"1.0": [35, 0, 0],
"1.6": [34.96463, -9.99962, 0.08301],
"2.0": [0.01002, 0.32522, 0.69041]
"0.0": [0, 0, 0],
"0.0833": {
"pre": [5, 0, 0],
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": ["-40-math.sin(q.anim_time*90*30)*1.5", 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-35, 0, 0],
"lerp_mode": "catmullrom"
},
"1.125": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.375": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.0833": [0, 0, 0],
"0.2083": {
"pre": [0, 0, -0.25],
"post": [0, 0, -0.25],
"lerp_mode": "catmullrom"
},
"1.125": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.375": [0, 0, 0]
}
},
"jaw": {
"rotation": {
"0.0": ["5-(math.sin(q.anim_time*90*2+90)*1-0.5)*1", 0, 0],
"0.05": ["-35-(math.sin(q.anim_time*90*2+90)*1-0.5)*1", 0, 0],
"0.5": ["27.5-(math.sin(q.anim_time*90*2+90)*1-0.5)*1", 0, 0],
"0.85": ["27.5-(math.sin(q.anim_time*90*2+90)*1-0.5)*1", 0, 0],
"1.1": ["-25-(math.sin(q.anim_time*90*2+90)*1-0.5)*1", 0, 0],
"1.15": ["-15-(math.sin(q.anim_time*90*2+90)*1-0.5)*0.5", 0, 0]
"0.0": [0, 0, 0],
"0.0833": {
"pre": [-5, 0, 0],
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [37.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [11.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [7.26, 0, 0],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"1.375": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.1": [-0.1, 0, 0],
"0.15": [0, 0, 0],
"1.1": [0, 0, 0],
"1.15": [-0.1, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.1": [0.1, 0, 0],
"0.15": [0, 0, 0],
"1.1": [0, 0, 0],
"1.15": [0.1, 0, 0]
}
},
"tail4": {
"neck2": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [22.5, 0, 0],
"0.65": [25, 0, 0],
"0.95": [32.5, 0, 0],
"1.0": [32.5, 0, 0],
"1.35": [39.56059, -8.33248, 5.56948],
"2.15": [0.00946, 0.60916, 0.36323]
"0.0833": {
"pre": [7.5, 0, 0],
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": [-5, 0, 0],
"1.125": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.375": [0, 0, 0]
}
},
"tail5": {
"rotation": {
"0.0": [5, 0, 0],
"0.1": [15, 0, 0],
"0.2": [25, 0, 0],
"0.5": [42.82744, -9.23501, -8.46088],
"0.55": [45.68718, -8.80348, -8.90928],
"0.65": [48.18718, -8.80348, -8.90928],
"1.0": [47.64681, 4.67606, 5.90982],
"1.45": [54.85234, 2.05205, 11.11128],
"2.3": [-0.0412, 8.51931, 0.3767]
}
},
"tail6": {
"neck": {
"rotation": {
"0.0": [0, 0, 0],
"0.05": [0, 0, 0],
"0.3": [22.5, 0, 0],
"0.65": [45, 0, 0],
"1.0": [45, 0, 0],
"1.55": [51.77676, 2.80672, 7.84455],
"2.45": [-1.96924, -1.43601, -6.55108]
}
},
"rattle": {
"rotation": {
"0.0": [0, 0, 0],
"0.05": [-10, 0, 0],
"0.75": [15, 0, 0],
"1.0": [15, 0, 0],
"1.65": [20, 10, 5],
"2.55": [0, -2.5, -2.5]
}
},
"rattle4": {
"rotation": {
"0.0": [0, 0, 0],
"0.1": [-10, 0, 0],
"0.55": [10, 0, 0],
"1.0": [15, 0, 0],
"1.75": [20, 10, 5],
"2.65": [2.5, -5, 0]
}
},
"rattle2": {
"rotation": {
"0.0": [0, 0, 0],
"0.05": [-20, 0, 0],
"1.0": [20, 0, 0],
"1.25": [15, 0, 0],
"1.9": [20, 10, 5],
"2.55": [-2.5, -2.5, -2.5]
}
},
"rattle3": {
"rotation": {
"0.0": [0, 0, 0],
"0.05": [-20, 0, 0],
"1.25": [25, 0, 0],
"1.5": [15, 0, 0],
"2.15": [20, 10, 5],
"2.55": [0, -2.5, -2.5]
}
},
"rattle5": {
"rotation": {
"0.0": [0, 0, 0],
"0.1": [-10, 0, 0],
"0.8": [20, 0, 0],
"1.25": [10, 0, 0],
"2.0": [15, 10, 5],
"2.65": [2.5, -5, 0]
"0.0833": {
"pre": [2.5, 0, 0],
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": [0, 0, 0],
"1.125": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.375": [0, 0, 0]
}
}
},
"sound_effects": {
"0.1667": {
"effect": "pokemon.ekans.cry"
}
}
},
"animation.ekans.sleep": {
"loop": true,
"bones": {
"ekans": {
"position": [0, 3, 7]
"body": {
"position": [0, 6, 0]
},
"head": {
"rotation": [42.91333, 68.7346, 43.12956]
"rotation": ["17.5-math.sin(q.anim_time*90-180)", -49, -6]
},
"jaw": {
"rotation": [-10, 0, 0]
},
"eyelid_right": {
"position": [-0.1, 0, 0]
},
"eyelid_left": {
"position": [0.1, 0, 0]
"neck2": {
"rotation": ["15-math.sin(q.anim_time*90-60)*0.75", -50, -7.5],
"position": [-0.25, 0, 0.5]
},
"tail": {
"rotation": [-7.5, 55, 0]
"rotation": [90, -32, -272.5],
"position": [-3, -0.5, 1],
"scale": 0
},
"tail2": {
"rotation": [-3.9416, -55.3577, -4.33386]
"rotation": [-176.62147, -67.38079, 169.49348]
},
"tail3": {
"rotation": [20.41084, -54.0129, -21.47388]
"rotation": [160, -85, -180]
},
"tail8": {
"rotation": [77.80887, 32.27264, 55.07287],
"position": [-1, -1.1, -2]
},
"tail9": {
"rotation": [18.4215, -23.19625, -12.13932]
},
"tail4": {
"rotation": [0, -62.5, 0]
"rotation": [87.73292, -75.69796, -92.26708]
},
"tail5": {
"rotation": [0, -55, 0]
"rotation": [-2.5, -87.5, 0]
},
"tail6": {
"rotation": [0, -57.5, 0]
"rotation": [0, -62.5, 0]
},
"rattle": {
"rotation": [-7.5, -62.5, 0]
"tail7": {
"rotation": [-1.41397, -67.50536, -1.13438]
},
"coiled_body": {
"rotation": [0, "-math.sin(q.anim_time*90-120)*0.25", 0],
"position": [0, 0, -3]
},
"coiled_body_top": {
"rotation": ["-math.sin(q.anim_time*90-60)*0.5", "math.sin(q.anim_time*90-60)*0.25", "-2.5-math.sin(q.anim_time*90*0.5+45)*0.5"]
},
"tail_rattle2": {
"rotation": [9.09308, -27.20461, 4.52273]
},
"eyelid_right": {
"position": [-1, 0, 0]
},
"neck": {
"rotation": ["-5-math.sin(q.anim_time*90)*0.75", 17.5, "-6.5+math.sin(q.anim_time*90*0.5-90)*0.5"],
"position": [-3.5, -0.75, 3.5]
},
"eyelid_left": {
"position": [1, 0, 0]
},
"coiled_tail": {
"rotation": [-2.5, "-40+math.sin(q.anim_time*90-30)", 0],
"position": [1, 0, 0]
},
"coiled_tail2": {
"rotation": [0, "-30+math.sin(q.anim_time*90-90)", 0]
},
"coiled_tail_rattle": {
"rotation": [-10, "-27.5+math.sin(q.anim_time*90-150)", 0]
},
"coiled_tail_rattle2": {
"rotation": [5, "math.sin(q.anim_time*90-210)", 0]
},
"coiled_tail_rattle3": {
"rotation": [0, "math.sin(q.anim_time*90-270)", 0]
}
}
},
"animation.ekans.cry": {
"animation_length": 0.95833,
"animation.ekans.recoil": {
"animation_length": 1,
"bones": {
"head": {
"rotation": {
"0.0": {
"0.0": [0, 0, 0],
"0.0833": {
"pre": [2.5, 0, 0],
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [-1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [-5, 0, 0],
"0.9583": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.0833": [0, 0, 0],
"0.2083": {
"pre": [0, 0, -0.25],
"post": [0, 0, -0.25],
"lerp_mode": "catmullrom"
},
"0.5833": {
"0.4583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": [0, 0, 0]
}
},
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": {
"pre": [-2.5, 0, 0],
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": [0, 0, 0]
}
},
"neck2": {
"rotation": {
"0.0": [0, 0, 0],
"0.0833": {
"pre": [15, 0, 0],
"post": [15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4583": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9583": [0, 0, 0]
}
},
"jaw": {
"pupil_right": {
"position": {
"0.0": [0, 0, 0],
"0.125": {"pre": [0, 0, 0], "post": [1, 0, 0]},
"0.5417": {"pre": [1, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [-1, 0, 0],
"0.125": {"pre": [-1, 0, 0], "post": [0, 0, 0]}
}
},
"pupil_surprised_right": {
"position": {
"0.0": [0, 0, 0],
"0.125": {"pre": [0, 0, 0], "post": [-1, 0, 0]},
"0.5417": {"pre": [-1, 0, 0], "post": [0, 0, 0]}
}
},
"neck": {
"rotation": {
"0.0": {
"0.0": [0, 0, 0],
"0.0833": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [14.79, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [12.5, 0, 0],
"post": [-10, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [14.79, 0, 0],
"0.4583": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [14.79, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"0.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9583": [0, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [1, 0, 0],
"0.125": {"pre": [1, 0, 0], "post": [0, 0, 0]}
}
},
"pupil_left": {
"position": {
"0.0": [0, 0, 0],
"0.125": {"pre": [0, 0, 0], "post": [-1, 0, 0]},
"0.5417": {"pre": [-1, 0, 0], "post": [0, 0, 0]}
}
},
"pupil_surprised_left": {
"position": {
"0.0": [0, 0, 0],
"0.125": {"pre": [0, 0, 0], "post": [1, 0, 0]},
"0.5417": {"pre": [1, 0, 0], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0833": {
"effect": "pokemon.ekans.cry"
}
},
"animation.ekans.walkspeedtest": {
"loop": true,
"bones": {
"body": {
"position": [0, 0, "120-q.anim_time*16*1.5"]
}
}
},
"animation.ekans.runspeedtest": {
"loop": true,
"bones": {
"body": {
"position": [0, 0, "120-q.anim_time*16*3.5"]
}
}
},
"animation.ekans.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": [0, 0, 0]
"0.0": [-1, 0, 0],
"0.1667": {"pre": [-1, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": [0, 0, 0]
"0.0": [1, 0, 0],
"0.1667": {"pre": [1, 0, 0], "post": [0, 0, 0]}
}
}
}
@@ -833,7 +833,7 @@
},
"sound_effects": {
"0.125": {
"effect": "pokemon.diglett_alolan.cry"
"effect": "pokemon.diglett.cry"
}
}
}
@@ -1,10 +1,10 @@
{
"format_version": "1.8.0",
"animations": {
"animation.poliwag.ground_idle": {
"animation.poliwag.ground_idle_placeholder": {
"loop": true,
"bones": {
"tail1": {
"tail": {
"rotation": [30, 0, 0]
},
"tail2": {
@@ -15,32 +15,28 @@
}
}
},
"animation.poliwag.ground_walk": {
"animation.poliwag.ground_walk_placeholder": {
"loop": true,
"bones": {
"body": {
"position": [0, "0 - (6/11) + math.abs(math.sin(((query.anim_time) - (1/3)) * 90 * 3) * (6/11))", 0]
},
"head": {
"rotation": ["0 - (0 * 1.5)", "math.sin(((query.anim_time) - (0.5/3)) * 90 * 3) * (4 * 1.5)", 0],
"position": [0, 0, "0 - (0 / 10)"]
},
"arm_left": {
"rotation": [0, "0 - math.sin(((query.anim_time) - (0.5/3)) * 90 * 3) * 28", "0 - -48"]
},
"arm_left2": {
"rotation": [0, "math.clamp(math.sin(((query.anim_time) + (0.75/3)) * 90 * 3) * 28, 0, 28)", 0]
},
"arm_right": {
"rotation": [0, "0 - math.sin(((query.anim_time) - (0.5/3)) * 90 * 3) * 28", -48]
},
"arm_right2": {
"rotation": [0, "0 - math.clamp(math.sin(((query.anim_time) - (0.75/3)) * 90 * 3) * 28, 0, 28)", 0]
},
"torso2": {
"rotation": [0, "0 - math.sin(((query.anim_time) - (0.5/3)) * 90 * 3) * 4", 0]
"body": {
"position": [0, "0 - (6/11) + math.abs(math.sin(((query.anim_time) - (1/3)) * 90 * 3) * (6/11))", 0]
},
"leg_left": {
"torso": {
"rotation": [0, "0 - math.sin(((query.anim_time) - (0.25/3)) * 90 * 3) * 4", 0]
},
"tail": {
"rotation": [30, 0, 0]
},
"tail2": {
"rotation": [15, 0, 0]
},
"tail3": {
"rotation": [15, 0, 0]
},
"left_leg": {
"rotation": [
"0 -math.sin((query.anim_time) * 90 * 3) * 6",
0,
@@ -48,10 +44,10 @@
],
"position": [0, "math.clamp(math.sin(((query.anim_time) + (1/3)) * 90 * 3) * 1, 0, 1)", 0]
},
"leg_left2": {
"rotation": ["0 - math.clamp(math.sin(((query.anim_time) - (0.75/3)) * 90 * 3) * 0, -0, 0)", 0, 0]
"left_foot": {
"rotation": ["0 - math.clamp(math.sin(((query.anim_time) - (0.75/3)) * 90 * 3) * v.foot, -v.foot, 0)", 0, 0]
},
"leg_right": {
"right_leg": {
"rotation": [
"math.sin((query.anim_time) * 90 * 3) * 6",
0,
@@ -59,39 +55,19 @@
],
"position": [0, "math.clamp(math.sin(((query.anim_time) - (1/3)) * 90 * 3) * 1, 0, 1)", 0]
},
"leg_right2": {
"rotation": ["math.clamp(math.sin(((query.anim_time) - (0.75/3)) * 90 * 3) * 0, 0, 0)", 0, 0]
},
"foot_left": {
"rotation": ["0 - math.clamp(math.sin(((query.anim_time) - (0.75/3)) * 90 * 3) * v.foot, -v.foot, 0)", 0, 0]
},
"foot_right": {
"right_foot": {
"rotation": ["math.clamp(math.sin(((query.anim_time) - (0.75/3)) * 90 * 3) * v.foot, 0, v.foot)", 0, 0]
},
"hand_right": {
"rotation": [0, -70, 0]
},
"hand_left": {
"rotation": [0, 70, 0]
},
"tail1": {
"rotation": [30, 0, 0]
},
"tail2": {
"rotation": [15, 0, 0]
},
"tail3": {
"rotation": [15, 0, 0]
},
"torso": {
"rotation": [0, "0 - math.sin(((query.anim_time) - (0.25/3)) * 90 * 3) * 4", 0]
}
}
},
"animation.poliwag.water_idle": {
"animation.poliwag.water_idle_placeholder": {
"loop": true,
"animation_length": 0.4583,
"bones": {
"tail1": {
"body": {
"rotation": [15, 0, 0]
},
"tail": {
"rotation": [-15, 0, 0]
},
"tail2": {
@@ -100,27 +76,27 @@
"tail3": {
"rotation": [15, 0, 0]
},
"body": {
"left_leg": {
"rotation": [15, 0, 0]
},
"leg_right": {
"left_foot": {
"rotation": [15, 0, 0]
},
"foot_right1": {
"right_leg": {
"rotation": [15, 0, 0]
},
"leg_left": {
"rotation": [15, 0, 0]
},
"foot_left1": {
"right_foot": {
"rotation": [15, 0, 0]
}
}
},
"animation.poliwag.water_swim": {
"animation.poliwag.water_swim_placeholder": {
"loop": true,
"bones": {
"tail1": {
"body": {
"rotation": [45, 0, 0]
},
"tail": {
"rotation": [-45, 0, 0]
},
"tail2": {
@@ -129,43 +105,54 @@
"tail3": {
"rotation": [5, 0, 0]
},
"body": {
"rotation": [45, 0, 0]
},
"leg_right": {
"left_leg": {
"rotation": [15, 0, 0]
},
"leg_left": {
"left_foot": {
"rotation": [15, 0, 0]
},
"foot_right1": {
"right_leg": {
"rotation": [15, 0, 0]
},
"foot_left1": {
"right_foot": {
"rotation": [15, 0, 0]
}
}
},
"animation.poliwag.blink": {
"animation_length": 0.16667,
"animation.poliwag.blink_placeholder": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"left_eyelid": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"right_eyelid": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"left_pupil": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
}
},
"right_pupil": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.poliwag.sleep": {
"animation.poliwag.sleep_placeholder": {
"loop": true,
"bones": {
"body": {
@@ -175,29 +162,6 @@
"eyelids": {
"position": [0, 0, -0.1]
},
"leg_right": {
"rotation": [-56.86824, 13.96782, -1.24205],
"position": [0, 0.25, -0.75]
},
"foot_right1": {
"rotation": [45, 0, 0]
},
"foot_right2": {
"rotation": [10, 0, 0]
},
"leg_left": {
"rotation": [-27.43103, -15.68951, 1.9062],
"position": [0, 0.5, -0.75]
},
"foot_left1": {
"rotation": [12.5, 0, 0]
},
"foot_left2": {
"rotation": [10, 0, 0]
},
"tail1": {
"rotation": [-0.16127, 25.11621, 5.5184]
},
"tail2": {
"rotation": [12.30936, 7.61658, -1.09051],
"position": [0, 0, -0.35]
@@ -206,52 +170,129 @@
"rotation": [10, 7.5, 0],
"position": [0, 0, -0.5]
},
"eyelid_left": {
"left_eyelid2": {
"position": [0, 0, -0.1]
},
"eyelid_right": {
"right_eyelid2": {
"position": [0, 0, -0.1]
}
}
},
"animation.poliwag.render": {
"loop": true,
"bones": {
"body": {
"rotation": [-5, 0, -10],
"position": [0, 6, 0]
},
"leg_right": {
"rotation": [24.26391, -14.269, 7.17267]
"tail": {
"rotation": [-0.16127, 25.11621, 5.5184]
},
"foot_right2": {
"left_leg": {
"rotation": [-27.43103, -15.68951, 1.9062],
"position": [0, 0.5, -0.75]
},
"left_foot": {
"rotation": [12.5, 0, 0]
},
"leg_left": {
"rotation": [17.44401, 5.64135, -19.34918]
"left_toe": {
"rotation": [10, 0, 0]
},
"foot_left2": {
"rotation": [-7.5, 0, 0]
"right_leg": {
"rotation": [-56.86824, 13.96782, 1.24205],
"position": [0, 0.25, -0.75]
},
"tail1": {
"rotation": [-63.87343, -4.37224, -50.6695]
"right_foot": {
"rotation": [45, 0, 0]
},
"tail2": {
"rotation": [0, 7.5, 0],
"position": [0, 0, -0.3]
},
"tail3": {
"rotation": [0, 0, 0]
"right_toe": {
"rotation": [10, 0, 0]
}
}
},
"animation.poliwag.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0417": {
"effect": "pokemon.poliwag.cry"
}
}
}
"animation.poliwag.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0417": {
"effect": "pokemon.poliwag.cry"
}
}
},
"animation.poliwag.test": {
"animation_length": 4,
"bones": {
"torso": {
"rotation": [-2.4905, 0.21782, 4.99527],
"position": [0, 0.25, 0]
},
"left_eye": {
"rotation": [0, 0, 0]
},
"right_eye": {
"rotation": [0, 0, 0]
},
"left_leg": {
"rotation": [20.22183, -9.6955, -1.73294],
"position": [0, 0, 0.25]
},
"left_foot": {
"rotation": [24.63136, -5.82612, 3.55184]
},
"right_leg": {
"rotation": [-32.29039, 6.33954, 2.12126],
"position": [-0.5, 0.5, -2]
},
"right_foot": {
"rotation": [2.92249, 12.46442, 1.89155]
},
"tail": {
"rotation": [34.30897, -18.48624, -45.57625]
},
"tail2": {
"rotation": [20, 0, 0]
},
"tail3": {
"rotation": [17.5, 0, 0]
},
"poliwag": {
"position": [0, 1, 0]
},
"mouth": {
"position": {
"0.0": [0, 0, 2],
"2.0": {"pre": [0, 0, 2], "post": [0, 0, 0]}
}
},
"left_toe": {
"rotation": [-45, 0, 0]
},
"right_toe": {
"rotation": [7.5, 0, 0],
"position": [0, 0, 0.15]
},
"mouth_open": {
"position": {
"0.0": [0, 0, -2],
"2.0": {"pre": [0, 0, -2], "post": [0, 0, 0]}
}
},
"eyelids": {
"position": {
"0.0": [0, 0, 0],
"1.5": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.6667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"left_eyelid": {
"position": [0.25, 0, 0]
},
"left_pupil": {
"position": {
"0.0": [0, 0, 0],
"1.5": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.6667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
},
"scale": [-1, 1, 1]
},
"right_pupil": {
"position": {
"0.0": [0, 0, 0],
"1.5": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.6667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
}
}
}
}
}
@@ -4,93 +4,937 @@
"animation.politoed.ground_idle": {
"loop": true,
"bones": {
"leftleg": {
"left_thigh": {
"rotation": [0, -5, 0]
},
"rightleg": {
"rotation": [0, 5, 0]
},
"leftarm": {
"left_arm": {
"rotation": [0, 0, 45]
},
"leftforearm": {
"left_lower_arm": {
"rotation": [0, 0, 15]
},
"rightarm": {
"right_thigh": {
"rotation": [0, 5, 0]
},
"right_arm": {
"rotation": [0, 0, -45]
},
"rightforearm": {
"right_lower_arm": {
"rotation": [0, 0, -15]
},
"tongue_long_base": {
"scale": 0
}
}
},
"animation.politoed.water_idle": {
"loop": true,
"bones": {
"leftleg": {
"rotation": [7.5, -5, 0]
},
"rightleg": {
"rotation": [7.5, 5, 0]
},
"leftarm": {
"rotation": [0, -10, 30]
},
"leftforearm": {
"rotation": [0, 0, 15]
},
"rightarm": {
"rotation": [0, 10, -30]
},
"rightforearm": {
"rotation": [0, 0, -15]
},
"body": {
"rotation": [30, 0, 0]
},
"head": {
"rotation": [-25, 0, 0]
},
"leftfoot": {
"left_thigh": {
"rotation": [7.5, -5, 0]
},
"left_foot": {
"rotation": [15, 0, 0]
},
"rightfoot": {
"left_arm": {
"rotation": [0, -10, 30]
},
"left_lower_arm": {
"rotation": [0, 0, 15]
},
"right_thigh": {
"rotation": [7.5, 5, 0]
},
"right_foot": {
"rotation": [15, 0, 0]
},
"right_arm": {
"rotation": [0, 10, -30]
},
"right_lower_arm": {
"rotation": [0, 0, -15]
},
"tongue_long_base": {
"scale": 0
}
}
},
"animation.politoed.water_swim": {
"loop": true,
"bones": {
"leftleg": {
"rotation": [15, -5, 0]
},
"rightleg": {
"rotation": [15, 5, 0]
},
"leftarm": {
"rotation": [0, -10, 45]
},
"leftforearm": {
"rotation": [0, 0, 15]
},
"rightarm": {
"rotation": [0, 10, -45]
},
"rightforearm": {
"rotation": [0, 0, -15]
},
"body": {
"rotation": [60, 0, 0]
},
"head": {
"rotation": [-55, 0, 0]
},
"leftfoot": {
"left_thigh": {
"rotation": [15, -5, 0]
},
"left_foot": {
"rotation": [30, 0, 0]
},
"rightfoot": {
"left_arm": {
"rotation": [0, -10, 45]
},
"left_lower_arm": {
"rotation": [0, 0, 15]
},
"right_thigh": {
"rotation": [15, 5, 0]
},
"right_foot": {
"rotation": [30, 0, 0]
},
"right_arm": {
"rotation": [0, 10, -45]
},
"right_lower_arm": {
"rotation": [0, 0, -15]
},
"tongue_long_base": {
"scale": 0
}
}
},
"animation.politoed.test": {
"loop": true,
"bones": {
"body": {
"position": [0, -0.5, 0]
},
"undefined": {
"rotation": [-30, 0, 0]
},
"torso": {
"position": [0, 0, 0]
},
"legs": {
"position": [0, -0.6, 0]
},
"left_thigh": {
"rotation": [-22, -31, -12.5],
"position": [0, 0, 0]
},
"left_leg": {
"rotation": [72.5, -10, 5]
},
"left_foot": {
"rotation": [-43, 0, 2.75],
"position": [0, 0.25, -0.25]
},
"head": {
"rotation": [-5, 0, 0]
},
"jaw": {
"rotation": [30, 0, 0]
},
"left_arm": {
"rotation": [0, 0, 42.5]
},
"left_lower_arm": {
"rotation": [0, 40, 0]
},
"left_hand": {
"rotation": [0, 0, 22.5],
"position": [-0.35, 0, 0]
},
"right_thigh": {
"rotation": [-22, 31, 12.5]
},
"right_leg": {
"rotation": [72.5, 10, -5]
},
"right_foot": {
"rotation": [-43, 0, -2.75],
"position": [0, 0.25, -0.25]
},
"right_arm": {
"rotation": [0, 0, -42.5]
},
"right_lower_arm": {
"rotation": [0, -40, 0]
},
"right_hand": {
"rotation": [0, 0, -22.5],
"position": [0.35, 0, 0]
},
"tongue_long_base": {
"rotation": [-27.5, 0, 0]
},
"tongue_long_mid": {
"rotation": [32.5, 0, 0]
},
"tongue_long_mid_bend": {
"rotation": [27.5, 0, 0]
},
"tongue_long_end": {
"rotation": [-20, 0, 0]
},
"tongue_long_tip": {
"rotation": [-37.5, 0, 0]
},
"left_leg_correction": {
"position": [0, 1, 0]
},
"right_leg_correction": {
"position": [0, 1, 0]
}
}
},
"animation.politoed.test2": {
"animation_length": 0.0417,
"bones": {
"body": {
"position": [0, -1.1, 0]
},
"undefined": {
"rotation": [-30, 0, 0]
},
"torso": {
"position": [0, 0, 0]
},
"legs": {
"position": [0, -0.6, 0]
},
"left_thigh": {
"rotation": [-58.0984, -35.5329, -3.9636],
"position": [0, 0, -0.25]
},
"left_leg": {
"rotation": [100.2268, -0.2874, 2.6377],
"position": [0, 0, 0.25]
},
"left_foot": {
"rotation": [-40, 0, 2.25],
"position": [0, 0.1, -0.25]
},
"jaw": {
"position": [0, 0, 0]
},
"left_arm": {
"rotation": [0, 0, 42.5]
},
"left_lower_arm": {
"rotation": [0, 40, 0]
},
"left_hand": {
"rotation": [0, 0, 22.5],
"position": [-0.35, 0, 0]
},
"right_thigh": {
"rotation": [-58.0984, 35.5329, 3.9636],
"position": [0, 0, -0.25]
},
"right_leg": {
"rotation": [100.2268, 0.2874, -2.6377],
"position": [0, 0, 0.25]
},
"right_foot": {
"rotation": [-40, 0, -2.25],
"position": [0, 0.1, -0.25]
},
"right_arm": {
"rotation": [0, 0, -42.5]
},
"right_lower_arm": {
"rotation": [0, -40, 0]
},
"right_hand": {
"rotation": [0, 0, -22.5],
"position": [0.35, 0, 0]
},
"tongue_long_base": {
"rotation": [-22.5, 0, 0]
},
"tongue_long_mid": {
"rotation": [32.5, 0, 0]
},
"tongue_long_mid_bend": {
"rotation": [27.5, 0, 0]
},
"tongue_long_end": {
"rotation": [-20, 0, 0]
},
"tongue_long_tip": {
"rotation": [-37.5, 0, 0]
},
"left_leg_correction": {
"position": [0, 1, 0]
},
"right_leg_correction": {
"position": [0, 1, 0]
}
}
},
"animation.politoed.test_walk": {
"loop": true,
"animation_length": 1,
"bones": {
"body": {
"position": [0, -0.5, 0]
},
"undefined": {
"rotation": [-30, 0, 0]
},
"torso": {
"rotation": ["-0+math.sin(q.anim_time*90*8-75)*3", "-0+math.sin(q.anim_time*90*4-240)*15", "0-math.sin(q.anim_time*90*4-240)*12.5"],
"position": [0, "0-math.sin(q.anim_time*90*8-75)*0.333", 0]
},
"legs": {
"position": [0, -0.6, 0]
},
"left_thigh": {
"rotation": {
"0.0": {
"post": [-45.8077, -17.7622, -4.8184],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-22, -31, -12.5],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [10.3458, -11.4389, -7.9978],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [11.7107, -12.7343, -7.9808],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [-71.94, -14.4638, -6.2564],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [-45.8077, -17.7622, -4.8184],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": {
"post": [0, 0, -1.25],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [0, 0.41, -1.06],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, -0.5, 2.5],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 1.5, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, -1.25],
"lerp_mode": "catmullrom"
}
}
},
"left_leg": {
"rotation": {
"0.0": {
"post": [11.153, -10.4048, 4.5735],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [72.5, -10, 5],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [64.434, -4.5354, 10.7584],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [87.0283, -5.4462, 9.7987],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [109.717, -7.2677, 7.8792],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [37.5, -10, 5],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [11.153, -10.4048, 4.5735],
"lerp_mode": "catmullrom"
}
}
},
"left_foot": {
"rotation": {
"0.0": {
"post": [4.441, -0.809, -3.8795],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-43, 0, 2.75],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-73.5885, -4.6063, 14.7348],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [-62.2404, -3.8386, 12.7373],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [-57.0442, -2.3032, 8.7424],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [4.4957, 0.1961, 0.2577],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [4.441, -0.809, -3.8795],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0.25, -0.25],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0.25, -1],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, -0.12, -0.75],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"left_toes": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [-34.9753, 1.3429, 2.1089],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head": {
"rotation": ["-0+math.sin(q.anim_time*90*8-105)*1.5", "-0+math.sin(q.anim_time*90*4-90)*7.5", "0-math.sin(q.anim_time*90*4-90)*5"]
},
"left_arm": {
"rotation": [0, "10+math.sin(q.anim_time*90*4-60)*22.5", "45-math.sin(q.anim_time*90*4+90)*15"]
},
"left_lower_arm": {
"rotation": [0, "25+math.sin(q.anim_time*90*4-90)*10", 0]
},
"left_hand": {
"rotation": [0, "2.5+math.sin(q.anim_time*90*4-120)*5", "22.5-math.sin(q.anim_time*90*4+450)*10"],
"position": [-0.35, 0, 0]
},
"right_thigh": {
"rotation": {
"0.0": {
"post": [10.3458, 11.4389, 7.9978],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [11.7107, 12.7343, 7.9808],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [-71.94, 14.4638, 6.2564],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-45.8077, 17.7622, 4.8184],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [-22, 31, 12.5],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [10.3458, 11.4389, 7.9978],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": {
"post": [0, -0.5, 2.5],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, 1.5, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, -1.25],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [0, 0.41, -1.06],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, -0.5, 2.5],
"lerp_mode": "catmullrom"
}
}
},
"right_leg": {
"rotation": {
"0.0": {
"post": [64.434, 4.5354, -10.7584],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [87.0283, 5.4462, -9.7987],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [109.717, 7.2677, -7.8792],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [37.5, 10, -5],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [11.153, 10.4048, -4.5735],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [72.5, 10, -5],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [64.434, 4.5354, -10.7584],
"lerp_mode": "catmullrom"
}
}
},
"right_foot": {
"rotation": {
"0.0": {
"post": [-73.5885, 4.6063, -14.7348],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [-62.2404, 3.8386, -12.7373],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [-57.0442, 2.3032, -8.7424],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [4.4957, -0.1961, -0.2577],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [4.441, 0.809, 3.8795],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [-43, 0, -2.75],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [-73.5885, 4.6063, -14.7348],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": {
"post": [0, 0.25, -1],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, -0.12, -0.75],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 0.25, -0.25],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0.25, -1],
"lerp_mode": "catmullrom"
}
}
},
"right_toes": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [-34.9753, -1.3429, -2.1089],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"hair": {
"rotation": ["-0+math.sin(q.anim_time*90*8-135)*2.5", "-0+math.sin(q.anim_time*90*4-300)*10", "0-math.sin(q.anim_time*90*4-300)*5"]
},
"right_arm": {
"rotation": [0, "-10+math.sin(q.anim_time*90*4-60)*22.5", "-45-math.sin(q.anim_time*90*4+90)*15"]
},
"right_lower_arm": {
"rotation": [0, "-25+math.sin(q.anim_time*90*4-90)*10", 0]
},
"right_hand": {
"rotation": [0, "-2.5+math.sin(q.anim_time*90*4-120)*5", "-22.5-math.sin(q.anim_time*90*4+450)*10"],
"position": [0.35, 0, 0]
},
"tongue_long_base": {
"rotation": [-27.5, 0, 0]
},
"tongue_long_mid": {
"rotation": [32.5, 0, 0]
},
"tongue_long_mid_bend": {
"rotation": [27.5, 0, 0]
},
"tongue_long_end": {
"rotation": [-20, 0, 0]
},
"tongue_long_tip": {
"rotation": [-37.5, 0, 0]
},
"left_leg_correction": {
"position": {
"0.0": {
"post": [0, 0.1, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0.1, 0],
"lerp_mode": "catmullrom"
}
}
},
"right_leg_correction": {
"position": {
"0.0": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.2083": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0.1, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 1, 0],
"lerp_mode": "catmullrom"
}
}
}
}
},
"animation.politoed.pose": {
"loop": true,
"bones": {
"body": {
"rotation": [-15, 0, 0],
"position": [0, 2, -2]
},
"left_thigh": {
"rotation": [-109.8093, -19.9813, 14.4472],
"position": [0.25, -1, 0.25]
},
"left_leg": {
"rotation": [62.5, 0, 0]
},
"left_foot": {
"rotation": [-15, 2.5, 0]
},
"head": {
"rotation": [10, 0, 0],
"position": [0, 0, -0.25]
},
"left_arm": {
"rotation": [-52.5, 0, 0],
"position": [0, -0.75, 0.25]
},
"left_lower_arm": {
"rotation": [0, 45, 0]
},
"left_hand": {
"rotation": [0, 0, 17.5],
"position": [-0.2, 0, 0]
},
"right_thigh": {
"rotation": [-109.8093, 19.9813, -14.4472],
"position": [-0.25, -1, 0.25]
},
"right_leg": {
"rotation": [62.5, 0, 0]
},
"right_foot": {
"rotation": [-15, -2.5, 0]
},
"left_pupil": {
"position": [0, -0.5, 0]
},
"right_pupil": {
"position": [0, -0.5, 0]
},
"right_arm": {
"rotation": [-52.5, 0, 0],
"position": [0, -0.75, 0.25]
},
"right_lower_arm": {
"rotation": [0, -45, 0]
},
"right_hand": {
"rotation": [0, 0, -17.5],
"position": [0.2, 0, 0]
},
"tongue_long_base": {
"scale": 0
}
}
},
"animation.politoed.blink": {
"animation_length": 0.2083,
"bones": {
"left_eye": {
"position": {
"0.0": [-0.1, 0, 0.1],
"0.1667": {
"pre": [-0.1, 0, 0.1],
"post": [-0.1, 0, 0.1]
},
"0.2083": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"right_eye": {
"position": {
"0.0": [0.1, 0, 0.1],
"0.1667": {
"pre": [0.1, 0, 0.1],
"post": [0.1, 0, 0.1]
},
"0.2083": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"left_eyelid": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.1667": {
"pre": [0.1, 0, -0.1],
"post": [0.1, 0, -0.1]
},
"0.2083": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"right_eyelid": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.1667": {
"pre": [-0.1, 0, -0.1],
"post": [-0.1, 0, -0.1]
},
"0.2083": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
}
}
}
},
"animation.politoed.happy": {
"loop": true,
"bones": {
"jaw": {
"rotation": [30, 0, 0]
},
"left_pupil": {
"position": [0, 0, 0]
},
"left_eyelid_happy": {
"position": [0.1, 0, -0.1]
},
"right_eyelid_happy": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.politoed.sad": {
"loop": true,
"bones": {
"left_eyelid_sad": {
"position": [0.1, 0, 0]
},
"right_eyelid_sad": {
"position": [-0.1, 0, 0]
}
}
},
"animation.politoed.angry": {
"loop": true,
"bones": {
"left_eyelid_angry": {
"position": [0.1, 0, -0.1]
},
"right_eyelid_angry": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.politoed.shocked": {
"loop": true,
"bones": {
"jaw": {
"rotation": [30, 0, 0]
},
"left_pupil": {
"position": [-0.1, 0, 0.3]
},
"right_pupil": {
"position": [0.1, 0, 0.3]
},
"left_pupil_shocked": {
"position": [0.1, 0, 0]
},
"right_pupil_shocked": {
"position": [-0.1, 0, 0]
}
}
},
"animation.politoed.unamused": {
"loop": true,
"bones": {
"left_eyelid_unamused": {
"position": [0.1, 0, -0.1]
},
"right_eyelid_unamused": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.politoed.hurt": {
"loop": true,
"bones": {
"jaw": {
"rotation": [30, 0, 0]
},
"left_eyelid_hurt": {
"position": [0.1, 0, -0.1]
},
"right_eyelid_hurt": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.politoed.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.04": {
"effect": "pokemon.politoed.cry"
}
}
}
@@ -62,7 +62,7 @@
"body": {
"rotation": [0, -7.5, 0]
},
"Eyebrow": {
"eyebrows": {
"rotation": [0, 0, 0]
}
}
@@ -240,7 +240,7 @@
"1.5": [0, 0, 0]
}
},
"Eyebrow": {
"eyebrows": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
@@ -282,31 +282,31 @@
"skirt_back": {
"rotation": ["0-math.cos(q.anim_time*90*2-30)*5", 0, 0]
},
"eyelid_left": {
"eyelid_annoyed_right": {
"position": [0, 0, -0.1]
},
"eyelid_right": {
"position": [0, 0, -0.1]
},
"Eyebrow": {
"eyebrows": {
"position": [0, "0+math.sin(q.anim_time*90*2-30)*0.05", 0]
},
"hair": {
"rotation": ["12.5+math.cos(q.anim_time*90*2-30)*3", 0, 0]
},
"eyelid_annoyed_left": {
"position": [0, 0, -0.1]
}
}
},
"animation.shroomish.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"eyelid_annoyed_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"eyelid_annoyed_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
@@ -591,7 +591,7 @@
"2.5833": [1, 1, 1]
}
},
"Eyebrow": {
"eyebrows": {
"rotation": [0, 0, 0],
"position": {
"0.0": [0, 0, 0],
@@ -603,17 +603,7 @@
"2.25": [0, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0833": [0, 0, -0.1],
"1.875": [0, 0, -0.1],
"1.9167": [0, 0, 0],
"2.1667": [0, 0, 0],
"2.2083": [0, 0, -0.1]
}
},
"eyelid_right": {
"eyelid_annoyed_right": {
"position": {
"0.0": [0, 0, 0],
"0.0833": [0, 0, -0.1],
@@ -636,6 +626,16 @@
"0.25": [0, 0, 0],
"0.2917": [0, 0, -0.1]
}
},
"eyelid_annoyed_left": {
"position": {
"0.0": [0, 0, 0],
"0.0833": [0, 0, -0.1],
"1.875": [0, 0, -0.1],
"1.9167": [0, 0, 0],
"2.1667": [0, 0, 0],
"2.2083": [0, 0, -0.1]
}
}
}
}
@@ -319,6 +319,144 @@
"position": [1, 1, 0]
}
}
},
"animation.bonsly.shoulder_left": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": [0, -30, 0]
},
"torso": {
"rotation": ["-10+math.sin(q.anim_time*90*2-90)*1.5", 0, "math.sin(q.anim_time*90*2/2-180)*1.5"],
"position": [0, 0, 0]
},
"stem": {
"rotation": ["math.sin(q.anim_time*90*2-90-90)*1", 0, 0]
},
"stem2": {
"rotation": ["math.sin(q.anim_time*90*2-150)*4", 0, 0]
},
"mouth_closed": {
"rotation": [0, 0, 180],
"position": [0, 0.75, 0]
},
"leg_left": {
"rotation": ["-66.956-math.sin(q.anim_time*90*3-90)*3.5", -37.4642, 3.1596],
"position": [0.5, "math.sin(q.anim_time*90*2/2-180)*-0.25", -1.25]
},
"leg_left2": {
"rotation": ["20-math.sin(q.anim_time*90*3-150)*15.5", 0, 0]
},
"foot_left": {
"rotation": ["40-math.sin(q.anim_time*90*3-210)*7.5", 0, 0]
},
"leg_right": {
"rotation": ["-58.8106+math.sin(q.anim_time*90*3-90)*3.5", 15.095, 8.959],
"position": [-0.25, "math.sin(q.anim_time*90*2/2-180)*0.1", -1.5]
},
"leg_right2": {
"rotation": ["20+math.sin(q.anim_time*90*3-150)*15.5", 0, 0]
},
"foot_right": {
"rotation": ["40+math.sin(q.anim_time*90*3-210)*7.5", 0, 0]
},
"pupil_left": {
"position": [-0.2, -0.1, 0]
},
"pupil_right": {
"position": [-0.1, -0.1, 0]
}
}
},
"animation.bonsly.shoulder_right": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": [0, 30, 0]
},
"torso": {
"rotation": ["-10+math.sin(q.anim_time*90*2-90)*1.5", 0, "-math.sin(q.anim_time*90*2/2-180)*1.5"],
"position": [0, 0, 0]
},
"stem": {
"rotation": ["math.sin(q.anim_time*90*2-90-90)*1", 0, 0]
},
"stem2": {
"rotation": ["math.sin(q.anim_time*90*2-150)*4", 0, 0]
},
"mouth_closed": {
"rotation": [0, 0, -180],
"position": [0, 0.75, 0]
},
"leg_left": {
"rotation": ["-58.8106+math.sin(q.anim_time*90*3-90)*3.5", -15.095, -8.959],
"position": [0.25, "math.sin(q.anim_time*90*2/2-180)*0.1", -1.5]
},
"leg_left2": {
"rotation": ["20+math.sin(q.anim_time*90*3-150)*15.5", 0, 0]
},
"foot_left": {
"rotation": ["40+math.sin(q.anim_time*90*3-210)*7.5", 0, 0]
},
"leg_right": {
"rotation": ["-66.956-math.sin(q.anim_time*90*3-90)*3.5", 37.4642, -3.1596],
"position": [-0.5, "math.sin(q.anim_time*90*2/2-180)*-0.25", -1.25]
},
"leg_right2": {
"rotation": ["20-math.sin(q.anim_time*90*3-150)*15.5", 0, 0]
},
"foot_right": {
"rotation": ["40-math.sin(q.anim_time*90*3-210)*7.5", 0, 0]
},
"pupil_left": {
"position": [0.1, -0.1, 0]
},
"pupil_right": {
"position": [0.2, -0.1, 0]
}
}
},
"animation.bonsly.shoulder_left_position": {
"loop": true,
"bones": {
"body": {
"position": [2.75, -4, -0.5]
}
}
},
"animation.bonsly.shoulder_right_position": {
"loop": true,
"bones": {
"body": {
"position": [-2.75, -4, -0.5]
}
}
},
"animation.bonsly.looktest": {
"loop": true,
"bones": {
"torso": {
"rotation": [0, 0, 0]
}
}
},
"animation.bonsly.scaletest": {
"loop": true,
"bones": {
"bonsly": {
"scale": 0.6
}
}
},
"animation.bonsly.walkspeedtest": {
"loop": true,
"bones": {
"bonsly": {
"position": [0, 0, "40-q.anim_time*90*0.2"]
}
}
}
}
}
@@ -0,0 +1,82 @@
{
"format_version": "1.8.0",
"animations": {
"animation.minior.ground_idle_meteor": {
"loop": true,
"animation_length": 8,
"bones": {
"body": {
"rotation": [0, 0, "-2*math.abs(query.anim_time*90/4)"],
"position": ["-2*math.sin(q.anim_time*90*0.5*2)", "3-1*math.sin(q.anim_time*90*2)", 0]
},
"face": {
"rotation": [0, 0, 0],
"position": [0, 0, 0]
},
"eye_left": {
"rotation": [0, 0, 0]
},
"eye_right": {
"rotation": [0, 0, 0]
},
"eyes": {
"scale": 0
},
"locator_item_hat": {
"scale": 1.1
}
}
},
"animation.minior.ground_idle_core": {
"loop": true,
"animation_length": 4,
"bones": {
"body": {
"rotation": [0, 0, "-2*math.abs(query.anim_time*90/2)"],
"position": ["-3*math.sin(q.anim_time*90*0.5*4)", "3-2*math.sin(q.anim_time*90*4)", 0]
},
"face": {
"rotation": [0, 0, "2*math.abs(query.anim_time*90/2)"],
"position": [0, 0, 0]
},
"eye_left": {
"rotation": [0, 0, 0]
},
"eye_right": {
"rotation": [0, 0, 0]
},
"shell": {
"scale": 0
}
}
},
"animation.minior.blink": {
"animation_length": 0.1667,
"bones": {
"eyes_ditto": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eyes_blink_ditto": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
}
},
"animation.minior.ditto": {
"loop": true,
"bones": {
"face": {
"scale": 0
},
"face_ditto": {
"position": [0, 0, -0.1]
}
}
}
}
}
@@ -4,16 +4,16 @@
{
"description": {
"identifier": "geometry.ekans",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 8,
"visible_bounds_height": 3,
"visible_bounds_offset": [0, 0.5, 0]
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 11,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "ekans",
"pivot": [0.5, 0, 0]
"pivot": [0, 0, -7]
},
{
"name": "locator_root",
@@ -34,277 +34,478 @@
{
"name": "body",
"parent": "ekans",
"pivot": [0, 2.5, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 4.5, -28.75],
"locators": {
"target": [0, 4.5, -28.75]
}
"pivot": [0, 0, -7]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 2.5, 2.75],
"pivot": [0, 2.5, 25],
"locators": {
"middle": [0, 2.5, 2.75]
"middle": [0, 2.5, 25]
}
},
{
"name": "head",
"name": "locator_target",
"parent": "body",
"pivot": [0, 3, -17.5],
"pivot": [0, 2.5, -26],
"locators": {
"target": [0, 2.5, -26]
}
},
{
"name": "neck",
"parent": "body",
"pivot": [0, 2, -1],
"cubes": [
{"origin": [-3, 0, -20.5], "size": [6, 6, 3], "inflate": 0.01, "uv": [22, 0]},
{"origin": [-3, 3, -25.5], "size": [6, 3, 5], "inflate": 0.01, "uv": [30, 29]},
{"origin": [-3, 1, -23.5], "size": [0, 2, 3], "inflate": 0.01, "uv": [0, -1]},
{"origin": [3, 1, -23.5], "size": [0, 2, 3], "inflate": 0.01, "uv": [0, -3]}
{"origin": [-2.5, 0, -9], "size": [5, 5, 9], "inflate": 0.04, "uv": [50, 23]}
]
},
{
"name": "locator_jaw_upper",
"parent": "head",
"pivot": [0, 3, -24.5],
"rotation": [-90, 0, 0],
"locators": {
"jaw1": [0, 3, -24.5]
}
"name": "neck2",
"parent": "neck",
"pivot": [0, 3, -9],
"cubes": [
{"origin": [-2.5, 0.2, -17], "size": [5, 5, 9], "inflate": 0.25, "uv": [32, 40]}
]
},
{
"name": "mouth",
"name": "head",
"parent": "neck2",
"pivot": [0, 4, -17]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 1.5, -21],
"locators": {
"mouth": [0, 1.5, -21],
"physical": [0, 1.5, -21],
"special": [0, 1.5, -21]
}
"pivot": [0, 4, -17]
},
{
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 4, -17],
"cubes": [
{"origin": [-3.5, -0.1, -19], "size": [7, 2, 3], "uv": [78, 31]},
{"origin": [-3.5, 2, -25], "size": [7, 4, 9], "inflate": 0.2, "uv": [0, 40]},
{"origin": [-3.5, -0.1, -21], "size": [1, 2, 2], "uv": [49, 91]},
{"origin": [2.5, -0.1, -21], "size": [1, 2, 2], "uv": [54, 91]}
]
},
{
"name": "locator_item_hat",
"parent": "head",
"pivot": [0, 6, -21.5],
"parent": "head_angle",
"pivot": [0, 6, -20],
"locators": {
"item_hat": [0, 6, -21.5]
}
},
{
"name": "locator_head",
"parent": "head",
"pivot": [0, 6, -23.5],
"locators": {
"head": [0, 6, -23.5]
"item_hat": [0, 6, -20]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 6.75, -27.55],
"parent": "head_angle",
"pivot": [0, 4, -25],
"locators": {
"item_face": [0, 4.5, -25.55]
"item_face": [0, 4, -25]
}
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 6.75, -28.2],
"name": "locator_jaw_upper",
"parent": "head_angle",
"pivot": [0, 2, -24],
"locators": {
"face": [0, 4.5, -25.55]
"jaw1": [0, 2, -24]
}
},
{
"name": "jaw",
"parent": "head",
"pivot": [0, 1, -20.5],
"cubes": [
{"origin": [-3, 0, -25], "size": [6, 1, 5], "uv": [30, 37]},
{"origin": [-2.985, 1, -22.5], "size": [0, 2, 2], "uv": [0, 4]},
{"origin": [2.985, 1, -22.5], "size": [0, 2, 2], "uv": [0, 2]}
]
},
{
"name": "locator_item",
"parent": "jaw",
"pivot": [0, 1, -25],
"locators": {
"item": [0, 1, -25]
}
},
{
"name": "locator_jaw_lower",
"parent": "jaw",
"pivot": [0, 1, -24],
"rotation": [90, 0, 0],
"locators": {
"jaw2": [0, 1, -24]
}
"name": "face",
"parent": "head_angle",
"pivot": [2.03333, 3.1, -19.2]
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 5.5, -21]
"parent": "face",
"pivot": [-3.7, 4.3, -19.8]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-3.015, 4.5, -21],
"rotation": [5, 0, 0],
"pivot": [-3.7, 4.3, -19.8],
"cubes": [
{"origin": [-3.015, 3.5, -22.5], "size": [0, 2, 3], "uv": [4, 1]}
{"origin": [-4.2, 3.3, -21.3], "size": [1, 2, 3], "uv": [88, 46]}
]
},
{
"name": "locator_eye_right",
"name": "eyelids_right",
"parent": "eye_right",
"pivot": [-3, 4.49753, -20.99866],
"locators": {
"eye1": [-3, 4.49753, -20.99866]
}
"pivot": [-3.7, 4.3, -19.8]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.415, 4.5, -21],
"parent": "eyelids_right",
"pivot": [-2.7, 4.3, -19.8],
"cubes": [
{"origin": [-2.915, 3.5, -22.5], "size": [1, 2, 3], "inflate": 0.01, "uv": [0, 16]}
{"origin": [-3.2, 3.3, -21.3], "size": [1, 2, 3], "inflate": 0.05, "uv": [1, 0]}
]
},
{
"name": "eyelid_sad_right",
"parent": "eyelids_right",
"pivot": [-2.7, 4.3, -19.8],
"cubes": [
{"origin": [-3.2, 3.3, -21.3], "size": [1, 2, 3], "inflate": 0.05, "uv": [0, 5]}
]
},
{
"name": "pupils_right",
"parent": "eye_right",
"pivot": [-3.7, 4.3, -19.8]
},
{
"name": "locator_eye_right",
"parent": "pupils_right",
"pivot": [-3.7, 4.3, -19.8],
"locators": {
"eye1": [-3.7, 4.3, -19.8]
}
},
{
"name": "pupil_right",
"parent": "pupils_right",
"pivot": [-3.7, 4.3, -19.8],
"cubes": [
{"origin": [-4.2, 3.3, -20.3], "size": [1, 2, 1], "inflate": 0.02, "uv": [0, 0]}
]
},
{
"name": "pupil_surprised_right",
"parent": "pupils_right",
"pivot": [-2.7, 4.3, -19.8],
"cubes": [
{"origin": [-3.2, 3.8, -20.3], "size": [1, 1, 1], "inflate": 0.02, "uv": [6, 0]}
]
},
{
"name": "pupil_happy_right",
"parent": "pupils_right",
"pivot": [-2.9, 4.4, -19.3],
"cubes": [
{"origin": [-3.41, 3.3, -21.3], "size": [1, 2, 3], "inflate": -0.2, "uv": [9, 0]}
]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [3.015, 4.5, -21],
"rotation": [5, 0, 0],
"pivot": [3.7, 4.3, -19.8],
"cubes": [
{"origin": [3.015, 3.5, -22.5], "size": [0, 2, 3], "uv": [4, 3]}
{"origin": [3.2, 3.3, -21.3], "size": [1, 2, 3], "uv": [88, 46], "mirror": true}
]
},
{
"name": "locator_eye_left",
"name": "eyelids_left",
"parent": "eye_left",
"pivot": [3, 4.49753, -20.99866],
"locators": {
"eye2": [3, 4.49753, -20.99866]
}
"pivot": [3.7, 4.3, -19.8]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.415, 4.5, -21],
"parent": "eyelids_left",
"pivot": [2.7, 4.3, -19.8],
"cubes": [
{"origin": [1.915, 3.5, -22.5], "size": [1, 2, 3], "inflate": 0.01, "uv": [0, 21]}
{"origin": [2.2, 3.3, -21.3], "size": [1, 2, 3], "inflate": 0.05, "uv": [1, 0], "mirror": true}
]
},
{
"name": "eyelid_sad_left",
"parent": "eyelids_left",
"pivot": [2.7, 4.3, -19.8],
"cubes": [
{"origin": [2.2, 3.3, -21.3], "size": [1, 2, 3], "inflate": 0.05, "uv": [0, 5], "mirror": true}
]
},
{
"name": "pupils_left",
"parent": "eye_left",
"pivot": [3.7, 4.3, -19.8]
},
{
"name": "locator_eye_left",
"parent": "pupils_left",
"pivot": [3.7, 4.3, -19.8],
"locators": {
"eye2": [3.7, 4.3, -19.8]
}
},
{
"name": "pupil_left",
"parent": "pupils_left",
"pivot": [3.7, 4.3, -19.8],
"cubes": [
{"origin": [3.2, 3.3, -20.3], "size": [1, 2, 1], "inflate": 0.02, "uv": [0, 0], "mirror": true}
]
},
{
"name": "pupil_surprised_left",
"parent": "pupils_left",
"pivot": [2.7, 4.3, -19.8],
"cubes": [
{"origin": [2.2, 3.8, -20.3], "size": [1, 1, 1], "inflate": 0.02, "uv": [6, 0], "mirror": true}
]
},
{
"name": "pupil_happy_left",
"parent": "pupils_left",
"pivot": [2.9, 4.4, -19.3],
"cubes": [
{"origin": [2.41, 3.3, -21.3], "size": [1, 2, 3], "inflate": -0.2, "uv": [9, 0], "mirror": true}
]
},
{
"name": "jaw",
"parent": "face",
"pivot": [-0.2, 1, -18],
"cubes": [
{"origin": [-3.49, 2, -20.5], "size": [0, 3, 4], "uv": [84, 55]},
{"origin": [3.49, 2, -20.5], "size": [0, 3, 4], "uv": [84, 62]},
{"origin": [-3.5, 0, -24.5], "size": [7, 2, 7], "inflate": -0.02, "uv": [74, 0]}
]
},
{
"name": "locator_item",
"parent": "jaw",
"pivot": [0, 2, -24.5],
"locators": {
"item": {
"offset": [0, 2, -24.5],
"rotation": [-90, 0, 0]
}
}
},
{
"name": "locator_jaw_lower2",
"parent": "jaw",
"pivot": [0, 2, -24],
"locators": {
"jaw2": [0, 2, -24]
}
},
{
"name": "ditto_eyes",
"parent": "face",
"pivot": [2.8, 4, -19.8],
"cubes": [
{"origin": [1.71, 3.6, -19.9], "size": [2, 1, 1], "inflate": 0.1, "uv": [50, 37]},
{"origin": [-3.71, 3.6, -19.9], "size": [2, 1, 1], "inflate": 0.1, "uv": [72, 51]}
]
},
{
"name": "locator_head",
"parent": "head_angle",
"pivot": [0, 6.2, -23],
"locators": {
"head": [0, 6.2, -23]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 3.2, -22],
"locators": {
"face": [0, 3.2, -22]
}
},
{
"name": "locator_mouth",
"parent": "head_angle",
"pivot": [0, 1.2, -25],
"locators": {
"mouth": [0, 1.2, -25],
"special": [0, 1.2, -25],
"physical": [0, 1.2, -25]
}
},
{
"name": "tail",
"parent": "body",
"pivot": [0, 2.5, -18],
"pivot": [0, 2, -1],
"cubes": [
{"origin": [-2.5, 0, -19], "size": [5, 5, 11], "inflate": 0.04, "uv": [0, 0]}
{"origin": [-2.5, 0, -1], "size": [5, 5, 9], "inflate": 0.03, "uv": [0, 53]}
]
},
{
"name": "tail2",
"parent": "tail",
"pivot": [0, 2.5, -9],
"pivot": [0, 2, 7],
"cubes": [
{"origin": [-2.5, 0, -9], "size": [5, 5, 10], "inflate": 0.03, "uv": [0, 16]}
{"origin": [-2.5, 0, 7], "size": [5, 5, 9], "inflate": 0.02, "uv": [56, 54]}
]
},
{
"name": "tail3",
"parent": "tail2",
"pivot": [0, 2.5, 0],
"pivot": [0, 2, 15],
"cubes": [
{"origin": [-2.5, 0, 0], "size": [5, 5, 10], "inflate": 0.02, "uv": [0, 31]}
{"origin": [-2.5, 0, 15], "size": [5, 5, 9], "inflate": 0.01, "uv": [28, 54]}
]
},
{
"name": "tail4",
"parent": "tail3",
"pivot": [0, 2.5, 9],
"pivot": [0, 2, 23],
"cubes": [
{"origin": [-2.5, 0, 9], "size": [5, 5, 10], "inflate": 0.01, "uv": [0, 46]}
{"origin": [-2.5, 0, 23], "size": [5, 5, 9], "inflate": 0.02, "uv": [60, 37]}
]
},
{
"name": "tail5",
"parent": "tail4",
"pivot": [0, 2.5, 18],
"pivot": [0, 2, 31],
"cubes": [
{"origin": [-2.5, 0, 18], "size": [5, 5, 9], "uv": [32, 0]}
]
},
{
"name": "tail6",
"parent": "tail5",
"pivot": [0, 2, 27],
"cubes": [
{"origin": [-2, 0, 26], "size": [4, 4, 11], "inflate": 0.01, "uv": [30, 14]}
{"origin": [-2.5, 0, 31], "size": [5, 5, 9], "inflate": 0.01, "uv": [0, 67]}
]
},
{
"name": "locator_tail",
"parent": "tail6",
"pivot": [0, 2, 31.5],
"rotation": [180, 0, -180],
"parent": "tail5",
"pivot": [0, 2.3, 34],
"locators": {
"tail": [0, 2, 31.5]
"tail": [0, 2.3, 34]
}
},
{
"name": "rattle",
"parent": "tail6",
"pivot": [0, 2, 37],
"cubes": [
{"origin": [-1.5, 0.5, 37], "size": [3, 3, 2], "uv": [30, 43]}
]
},
{
"name": "rattle2",
"parent": "rattle",
"name": "tail6",
"parent": "tail5",
"pivot": [0, 2, 39],
"cubes": [
{"origin": [-1, 1, 38.75], "size": [2, 2, 1], "uv": [40, 51]},
{"origin": [-1.5, 0.5, 39.5], "size": [3, 3, 2], "uv": [30, 48]}
{"origin": [-2.5, 0, 39], "size": [5, 5, 9], "inflate": 0.02, "uv": [28, 68]}
]
},
{
"name": "rattle3",
"parent": "rattle2",
"pivot": [0, 2, 41.5],
"name": "tail7",
"parent": "tail6",
"pivot": [0, 2, 47],
"cubes": [
{"origin": [-1, 1, 41.25], "size": [2, 2, 1], "uv": [40, 54]},
{"origin": [-1.5, 0.5, 42], "size": [3, 3, 2], "uv": [30, 53]}
{"origin": [-2.5, 0, 47], "size": [5, 5, 9], "inflate": 0.01, "uv": [56, 68]}
]
},
{
"name": "rattle4",
"parent": "rattle3",
"pivot": [0, 2, 44],
"name": "tail8",
"parent": "tail7",
"pivot": [0, 2, 55],
"cubes": [
{"origin": [-0.5, 1.5, 43.75], "size": [1, 1, 1], "uv": [48, 43]},
{"origin": [-1, 1, 44.5], "size": [2, 2, 2], "uv": [40, 43]}
{"origin": [-2, 0.4, 55], "size": [4, 4, 7], "inflate": 0.25, "uv": [74, 9]}
]
},
{
"name": "rattle5",
"parent": "rattle4",
"pivot": [0, 2, 46.5],
"name": "tail9",
"parent": "tail8",
"pivot": [0, 2, 61],
"cubes": [
{"origin": [-0.5, 1.5, 46.25], "size": [1, 1, 1], "uv": [48, 45]},
{"origin": [-1, 1, 47], "size": [2, 2, 2], "uv": [40, 47]}
{"origin": [-2, 0.3, 61], "size": [4, 4, 6], "uv": [0, 81]}
]
},
{
"name": "tail_rattle",
"parent": "tail9",
"pivot": [0, 2, 66],
"cubes": [
{"origin": [-1, 1.3, 65.9], "size": [2, 2, 6], "uv": [54, 89]},
{"origin": [-1, 1.3, 67.4], "size": [2, 2, 2], "inflate": 0.35, "uv": [57, 85]}
]
},
{
"name": "tail_rattle2",
"parent": "tail_rattle",
"pivot": [0, 2.2, 71],
"cubes": [
{"origin": [-0.5, 1.8, 73.7], "size": [1, 1, 1], "inflate": 0.2, "uv": [87, 74]},
{"origin": [-0.5, 1.8, 71.2], "size": [1, 1, 2], "inflate": 0.3, "uv": [86, 76]}
]
},
{
"name": "tail_rattle3",
"parent": "tail_rattle2",
"pivot": [0, 2.4, 74],
"cubes": [
{"origin": [-0.5, 1.8, 73.7], "size": [1, 1, 2], "uv": [86, 71]}
]
},
{
"name": "locator_tail_tip",
"parent": "rattle5",
"pivot": [0, 2, 49],
"rotation": [180, 0, -180],
"parent": "tail_rattle3",
"pivot": [0, 2.2, 75.7],
"locators": {
"tail_tip": [0, 2, 49]
"tail_tip": [0, 2.2, 75.7]
}
},
{
"name": "coiled_body",
"parent": "ekans",
"pivot": [0, 0, 2],
"cubes": [
{"origin": [-9.5, 0, -7], "size": [19, 5, 18], "uv": [0, 0]}
]
},
{
"name": "coiled_tail",
"parent": "coiled_body",
"pivot": [6, 2, 10],
"cubes": [
{"origin": [4, 0.4, 10], "size": [4, 4, 7], "inflate": 0.25, "uv": [74, 9]}
]
},
{
"name": "coiled_tail2",
"parent": "coiled_tail",
"pivot": [6, 2, 16],
"cubes": [
{"origin": [4, 0.3, 16], "size": [4, 4, 6], "uv": [0, 81]}
]
},
{
"name": "locator_coiled_tail",
"parent": "coiled_tail2",
"pivot": [6, 2.2, 19.7],
"locators": {
"coiled_tail": [6, 2.2, 19.7]
}
},
{
"name": "coiled_tail_rattle",
"parent": "coiled_tail2",
"pivot": [6, 2, 21],
"cubes": [
{"origin": [5, 1.3, 20.9], "size": [2, 2, 6], "uv": [54, 89]},
{"origin": [5, 1.3, 22.4], "size": [2, 2, 2], "inflate": 0.35, "uv": [57, 85]}
]
},
{
"name": "coiled_tail_rattle2",
"parent": "coiled_tail_rattle",
"pivot": [6, 2.2, 26],
"cubes": [
{"origin": [5.5, 1.8, 28.7], "size": [1, 1, 1], "inflate": 0.2, "uv": [87, 74]},
{"origin": [5.5, 1.8, 26.2], "size": [1, 1, 2], "inflate": 0.3, "uv": [86, 76]}
]
},
{
"name": "coiled_tail_rattle3",
"parent": "coiled_tail_rattle2",
"pivot": [6, 2.4, 29],
"cubes": [
{"origin": [5.5, 1.8, 28.7], "size": [1, 1, 2], "uv": [86, 71]}
]
},
{
"name": "locator_coiled_tail_tip",
"parent": "coiled_tail_rattle3",
"pivot": [6, 2.2, 30.7],
"locators": {
"coiled_tail_tip": [6, 2.2, 30.7]
}
},
{
"name": "coiled_body_top",
"parent": "coiled_body",
"pivot": [0, 7, 2],
"cubes": [
{"origin": [-6.5, 4.5, -4], "size": [13, 5, 12], "uv": [0, 23]}
]
}
]
}
@@ -15,347 +15,6 @@
"name": "oddish",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "oddish",
"pivot": [0, 5.5, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 5.5, 0],
"cubes": [
{"origin": [-4.5, 2, -3], "size": [9, 7, 6], "uv": [0, 0]}
]
},
{
"name": "mouth",
"parent": "torso",
"pivot": [0, 4, -2.905]
},
{
"name": "mouth_closed",
"parent": "mouth",
"pivot": [0, 4, -3.01],
"cubes": [
{"origin": [-1, 3.5, -3.01], "size": [2, 1, 0], "uv": [60, 12], "mirror": true}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 4, -2.91],
"cubes": [
{"origin": [-1, 3, -2.91], "size": [2, 2, 0], "uv": [54, 0]}
]
},
{
"name": "locator_mouth",
"parent": "mouth",
"pivot": [0, 4, -3],
"locators": {
"mouth": [0, 4, -3]
}
},
{
"name": "eyes",
"parent": "torso",
"pivot": [0, 5.5, -3.025]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2, 5.5, -3.01],
"cubes": [
{"origin": [-2.5, 5, -3.01], "size": [1, 1, 0], "uv": [62, 0]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.25, 6, -2.41],
"cubes": [
{"origin": [-3.25, 5, -2.91], "size": [2, 2, 1], "inflate": 0.01, "uv": [58, 2], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2, 5.5, -3],
"locators": {
"eye1": [-2, 5.5, -3]
}
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2, 5.5, -3.01],
"cubes": [
{"origin": [1.5, 5, -3.01], "size": [1, 1, 0], "uv": [62, 0], "mirror": true}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.25, 6, -2.41],
"cubes": [
{"origin": [1.25, 5, -2.91], "size": [2, 2, 1], "inflate": 0.01, "uv": [58, 2]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2, 5.5, -3],
"locators": {
"eye2": [2, 5.5, -3]
}
},
{
"name": "leaves",
"parent": "torso",
"pivot": [0, 5.5, 0]
},
{
"name": "leaf_center",
"parent": "leaves",
"pivot": [0, 9, -1.5],
"cubes": [
{"origin": [-2.5, 9, -1.5], "size": [5, 5, 0], "uv": [30, 17]}
]
},
{
"name": "leaf_center2",
"parent": "leaf_center",
"pivot": [0, 14, -1.5],
"rotation": [-15, 0, 0],
"cubes": [
{"origin": [-2.5, 14, -1.5], "size": [5, 6, 0], "uv": [30, 11]},
{"origin": [-0.5, 20, -1.5], "size": [2, 0, 2], "pivot": [0.5, 20, -1.5], "rotation": [-22.5, 0, 0], "uv": [0, 0]}
]
},
{
"name": "locator_special",
"parent": "leaf_center2",
"pivot": [0, 15.5, -1.5],
"locators": {
"special": [0, 15.5, -1.5]
}
},
{
"name": "leaf_front_right",
"parent": "leaves",
"pivot": [-2.75, 9, -1.25],
"rotation": [0, 22.5, -30],
"cubes": [
{"origin": [-5.25, 8, -1.25], "size": [5, 5, 0], "uv": [30, 6]}
]
},
{
"name": "leaf_front_right2",
"parent": "leaf_front_right",
"pivot": [-2.75, 13, -1.25],
"rotation": [-10, 0, 0],
"cubes": [
{"origin": [-5.25, 13, -1.25], "size": [5, 6, 0], "uv": [30, 0]}
]
},
{
"name": "leaf_front_left",
"parent": "leaves",
"pivot": [2.75, 9, -1.25],
"rotation": [0, -22.5, 30],
"cubes": [
{"origin": [0.25, 8, -1.25], "size": [5, 5, 0], "uv": [20, 26]}
]
},
{
"name": "leaf_front_left2",
"parent": "leaf_front_left",
"pivot": [2.75, 13, -1.25],
"rotation": [-10, 0, 0],
"cubes": [
{"origin": [0.25, 13, -1.25], "size": [5, 6, 0], "uv": [20, 21]}
]
},
{
"name": "leaf_back_right",
"parent": "leaves",
"pivot": [-1.25, 9, 0],
"rotation": [-5, -7.5, -10],
"cubes": [
{"origin": [-4.2716, 8.75215, 0.02454], "size": [5, 5, 0], "uv": [10, 27]}
]
},
{
"name": "leaf_back_right2",
"parent": "leaf_back_right",
"pivot": [-1.7716, 13.75215, 0.02454],
"rotation": [-5, 0, 0],
"cubes": [
{"origin": [-4.2716, 13.75215, 0.02454], "size": [5, 6, 0], "uv": [10, 21]}
]
},
{
"name": "leaf_back_left",
"parent": "leaves",
"pivot": [1.25, 9, 0.5],
"rotation": [-5, 7.5, 10],
"cubes": [
{"origin": [-0.75, 8.75, 0.5], "size": [5, 5, 0], "uv": [0, 26]}
]
},
{
"name": "leaf_back_left2",
"parent": "leaf_back_left",
"pivot": [1.75, 13.75, 0.5],
"rotation": [-5, 0, 0],
"cubes": [
{"origin": [-0.75, 13.75, 0.5], "size": [5, 6, 0], "uv": [0, 20]}
]
},
{
"name": "head_locators",
"parent": "torso",
"pivot": [0, 9, -1.5]
},
{
"name": "locator_head",
"parent": "head_locators",
"pivot": [0, 9, -1.5],
"locators": {
"head": [0, 9, -1.5]
}
},
{
"name": "locator_item_hat",
"parent": "head_locators",
"pivot": [0, 9, 0],
"locators": {
"item_hat": [0, 9, 0]
}
},
{
"name": "locator_face",
"parent": "head_locators",
"pivot": [0, 5.5, -3],
"locators": {
"face": [0, 5.5, -3]
}
},
{
"name": "locator_item_face",
"parent": "head_locators",
"pivot": [0, 5.5, -3],
"locators": {
"item_face": [0, 5.5, -3]
}
},
{
"name": "locator_physical",
"parent": "head_locators",
"pivot": [0, 7.5, -3],
"locators": {
"physical": [0, 7.5, -3]
}
},
{
"name": "locator_item",
"parent": "torso",
"pivot": [-4.5, 5.5, 0],
"rotation": [0, 180, -90],
"locators": {
"item": [-4.5, 5.5, 0]
}
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 5.5, 0]
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-2, 2, 0.25],
"cubes": [
{"origin": [-2.5, 0.5, -0.25], "size": [1, 2, 1], "uv": [0, 2]}
]
},
{
"name": "foot_right",
"parent": "leg_right",
"pivot": [-2, 1, 0.25],
"rotation": [0, 5, 0],
"cubes": [
{"origin": [-3.5, 0, -1.25], "size": [3, 1, 3], "uv": [15, 14]}
]
},
{
"name": "foot_right2",
"parent": "foot_right",
"pivot": [-2, 0, -1.25],
"cubes": [
{"origin": [-3.5, 0, -3.25], "size": [3, 1, 2], "inflate": 0.01, "uv": [4, 17]}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right2",
"pivot": [-2, 0.5, -2],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-2, 0.5, -2]
}
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [2, 2, 0.25],
"cubes": [
{"origin": [1.5, 0.5, -0.25], "size": [1, 2, 1], "uv": [0, 2]}
]
},
{
"name": "foot_left",
"parent": "leg_left",
"pivot": [2, 1, 0.25],
"rotation": [0, -5, 0],
"cubes": [
{"origin": [0.5, 0, -1.25], "size": [3, 1, 3], "uv": [3, 13]}
]
},
{
"name": "foot_left2",
"parent": "foot_left",
"pivot": [2, 0, -1.25],
"cubes": [
{"origin": [0.5, 0, -3.25], "size": [3, 1, 2], "inflate": 0.01, "uv": [16, 18]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left2",
"pivot": [2, 0.5, -2],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [2, 0.5, -2]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 9, 0],
"locators": {
"middle": [0, 9, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 5.5, -4],
"locators": {
"target": [0, 5.5, -4]
}
},
{
"name": "locator_root",
"parent": "oddish",
@@ -371,6 +30,519 @@
"locators": {
"top": [0, 18, 0]
}
},
{
"name": "body",
"parent": "oddish",
"pivot": [0, 5.5, 0]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 8, 0],
"locators": {
"middle": [0, 8, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 5.5, -5],
"locators": {
"target": [0, 5.5, -5]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 4.5, 0]
},
{
"name": "head_ai",
"parent": "torso",
"pivot": [0, 4.5, 0],
"cubes": [
{"origin": [-4.5, 2, -4], "size": [9, 7, 8], "uv": [0, 0]}
]
},
{
"name": "locator_physical",
"parent": "head_ai",
"pivot": [0, 7.5, -4],
"locators": {
"physical": [0, 7.5, -4]
}
},
{
"name": "locator_item_face",
"parent": "head_ai",
"pivot": [0, 6.35, -4],
"locators": {
"item_face": [0, 6.35, -4]
}
},
{
"name": "locator_face",
"parent": "head_ai",
"pivot": [0, 5.5, -4],
"locators": {
"face": [0, 5.5, -4]
}
},
{
"name": "locator_item_hat",
"parent": "head_ai",
"pivot": [0, 9.5, 0],
"locators": {
"item_hat": [0, 9.5, 0]
}
},
{
"name": "locator_head",
"parent": "head_ai",
"pivot": [0, 9, -4],
"locators": {
"head": [0, 9, -4]
}
},
{
"name": "face",
"parent": "head_ai",
"pivot": [0, 5, -4]
},
{
"name": "mouth",
"parent": "face",
"pivot": [0, 4.25, -3.905]
},
{
"name": "mouth_closed",
"parent": "mouth",
"pivot": [0, 4.5, -4.01],
"cubes": [
{"origin": [-1.5, 4, -4.01], "size": [1, 1, 1], "uv": [0, 4]},
{"origin": [0.5, 4, -4.01], "size": [1, 1, 1], "uv": [4, 4]}
]
},
{
"name": "mouth_closed2",
"parent": "mouth_closed",
"pivot": [0, 4, -4.01],
"cubes": [
{"origin": [-0.5, 3.5, -4.01], "size": [1, 1, 1], "inflate": 0.01, "uv": [0, 6]}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 4.5, -3.91],
"cubes": [
{"origin": [-1.5, 4, -3.91], "size": [3, 1, 1], "uv": [19, 16]}
]
},
{
"name": "mouth_open2",
"parent": "mouth_open",
"pivot": [0, 4, -3.91],
"cubes": [
{"origin": [-1, 3.5, -3.91], "size": [2, 1, 1], "inflate": 0.01, "uv": [27, 16]}
]
},
{
"name": "mouth_open_small",
"parent": "mouth",
"pivot": [0, 4.5, -3.91],
"cubes": [
{"origin": [-0.5, 3.5, -3.91], "size": [1, 2, 1], "uv": [59, 16]}
]
},
{
"name": "locator_mouth",
"parent": "mouth",
"pivot": [0, 4, -4],
"locators": {
"mouth": [0, 4, -4],
"special": [0, 4, -4]
}
},
{
"name": "locator_item",
"parent": "mouth",
"pivot": [0, 4, -4],
"rotation": [90, 0, 0],
"locators": {
"item": {
"offset": [0, 4, -4],
"rotation": [0, 45, 0]
}
}
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 6, -4.025]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2, 6, -4.01],
"cubes": [
{"origin": [1.5, 5.5, -4.01], "size": [1, 1, 1], "inflate": 0.01, "uv": [11, 16]}
]
},
{
"name": "eye_expression_left",
"parent": "eye_left",
"pivot": [2, 6.5, -3.91],
"cubes": [
{"origin": [1.5, 6, -3.91], "size": [1, 1, 1], "inflate": 0.02, "uv": [0, 0]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2, 6, -4],
"locators": {
"eye2": [2, 6, -4]
}
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2, 6, -4.01],
"cubes": [
{"origin": [-2.5, 5.5, -4.01], "size": [1, 1, 1], "inflate": 0.01, "uv": [15, 16], "mirror": true}
]
},
{
"name": "eye_expression_right",
"parent": "eye_right",
"pivot": [-2, 6.5, -3.91],
"cubes": [
{"origin": [-2.5, 6, -3.91], "size": [1, 1, 1], "inflate": 0.02, "uv": [4, 0], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2, 6, -4],
"locators": {
"eye1": [-2, 6, -4]
}
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [1.5, 6.25, -3.41],
"cubes": [
{"origin": [1, 5.25, -3.91], "size": [2, 2, 1], "uv": [34, 10]}
]
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-1.5, 6.25, -3.41],
"cubes": [
{"origin": [-3, 5.25, -3.91], "size": [2, 2, 1], "uv": [34, 7], "mirror": true}
]
},
{
"name": "eyelid_happy_left",
"parent": "eyes",
"pivot": [1.5, 6.25, -3.41],
"cubes": [
{"origin": [1, 5.25, -3.91], "size": [2, 2, 1], "uv": [40, 10]},
{"origin": [1.5, 5.75, -3.92], "size": [1, 1, 1], "inflate": 0.02, "uv": [0, 2]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eyes",
"pivot": [-1.5, 6.25, -3.41],
"cubes": [
{"origin": [-3, 5.25, -3.91], "size": [2, 2, 1], "uv": [40, 7], "mirror": true},
{"origin": [-2.5, 5.75, -3.92], "size": [1, 1, 1], "inflate": 0.02, "uv": [4, 2], "mirror": true}
]
},
{
"name": "eyelid_recoil_left",
"parent": "eyes",
"pivot": [2, 6.25, -3.41],
"cubes": [
{"origin": [1, 5.25, -3.91], "size": [2, 2, 1], "uv": [46, 10]}
]
},
{
"name": "eyelid_recoil_right",
"parent": "eyes",
"pivot": [-2, 6.25, -3.41],
"cubes": [
{"origin": [-3, 5.25, -3.91], "size": [2, 2, 1], "uv": [46, 7], "mirror": true}
]
},
{
"name": "face_ditto",
"parent": "head_ai",
"pivot": [0, 4.75, -3.9]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 5.5, -3.92],
"cubes": [
{"origin": [-3, 5, -3.92], "size": [6, 1, 0], "uv": [52, 7]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 5.5, -3.82],
"cubes": [
{"origin": [-3.5, 5, -3.82], "size": [7, 1, 0], "uv": [50, 4]},
{"origin": [-3, 5.5, -3.83], "size": [6, 1, 0], "uv": [52, 9]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 3.75, -3.9],
"cubes": [
{"origin": [-2.5, 3, -3.91], "size": [5, 1, 0], "uv": [54, 11]},
{"origin": [-3.5, 3.5, -3.91], "size": [7, 1, 0], "uv": [50, 5]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 3.5, -3.81],
"cubes": [
{"origin": [-3.5, 2.5, -3.81], "size": [7, 2, 0], "uv": [50, 13]}
]
},
{
"name": "leaves",
"parent": "head_ai",
"pivot": [0, 9, -1]
},
{
"name": "leaf_center",
"parent": "leaves",
"pivot": [0, 9, -1],
"rotation": [-2.5, 0, 0],
"cubes": [
{"origin": [-2.5, 9, -1], "size": [5, 5, 0], "uv": [1, 26]}
]
},
{
"name": "leaf_center2",
"parent": "leaf_center",
"pivot": [0, 14, -1],
"cubes": [
{"origin": [-2.5, 14, -1], "size": [5, 7, 0], "uv": [1, 18]}
]
},
{
"name": "leaf_center3",
"parent": "leaf_center2",
"pivot": [0.5, 21, -1],
"cubes": [
{"origin": [-1.5, 21, -1], "size": [3, 0, 3], "uv": [31, 16]}
]
},
{
"name": "leaf_inner_left",
"parent": "leaves",
"pivot": [1, 9, -0.75],
"rotation": [0, 0, 35]
},
{
"name": "leaf_inner_rotation_left",
"parent": "leaf_inner_left",
"pivot": [1, 9, -0.75],
"rotation": [-22.5, -5, 0],
"cubes": [
{"origin": [-1.5, 9, -0.75], "size": [5, 5, 0], "uv": [23, 26]}
]
},
{
"name": "leaf_inner_left2",
"parent": "leaf_inner_rotation_left",
"pivot": [1, 14, -0.75],
"cubes": [
{"origin": [-1.5, 14, -0.75], "size": [5, 6, 0], "uv": [23, 19]}
]
},
{
"name": "leaf_inner_left3",
"parent": "leaf_inner_left2",
"pivot": [1, 20, -0.75],
"cubes": [
{"origin": [-0.5, 20, -0.75], "size": [4, 3, 0], "uv": [50, 16]}
]
},
{
"name": "leaf_inner_right",
"parent": "leaves",
"pivot": [-1, 9, -0.75],
"rotation": [0, 0, -35]
},
{
"name": "leaf_inner_rotation_right",
"parent": "leaf_inner_right",
"pivot": [-1, 9, -0.75],
"rotation": [-22.5, 5, 0],
"cubes": [
{"origin": [-3.5, 9, -0.75], "size": [5, 5, 0], "uv": [34, 26], "mirror": true}
]
},
{
"name": "leaf_inner_right2",
"parent": "leaf_inner_rotation_right",
"pivot": [-1, 14, -0.75],
"cubes": [
{"origin": [-3.5, 14, -0.75], "size": [5, 6, 0], "uv": [12, 19], "mirror": true}
]
},
{
"name": "leaf_inner_right3",
"parent": "leaf_inner_right2",
"pivot": [-1, 20, -0.75],
"cubes": [
{"origin": [-3.5, 20, -0.75], "size": [4, 3, 0], "uv": [41, 16], "mirror": true}
]
},
{
"name": "leaf_outer_left",
"parent": "leaves",
"pivot": [0.5, 9, -1],
"rotation": [0, 0, 70]
},
{
"name": "leaf_outer_rotation_left",
"parent": "leaf_outer_left",
"pivot": [0.5, 9, -1],
"rotation": [-7.5, 7.5, 0],
"cubes": [
{"origin": [-2, 9, -1], "size": [5, 5, 0], "uv": [45, 26]}
]
},
{
"name": "leaf_outer_left2",
"parent": "leaf_outer_rotation_left",
"pivot": [0.5, 14, -1],
"cubes": [
{"origin": [-2, 14, -1], "size": [5, 5, 0], "uv": [45, 20]}
]
},
{
"name": "leaf_outer_left3",
"parent": "leaf_outer_left2",
"pivot": [0.5, 19, -1],
"cubes": [
{"origin": [0, 19, -1], "size": [3, 3, 0], "uv": [56, 28]}
]
},
{
"name": "leaf_outer_right",
"parent": "leaves",
"pivot": [-0.5, 9, -1],
"rotation": [0, 0, -70]
},
{
"name": "leaf_outer_rotation_right",
"parent": "leaf_outer_right",
"pivot": [-0.5, 9, -1],
"rotation": [-7.5, -7.5, 0],
"cubes": [
{"origin": [-3, 9, -1], "size": [5, 5, 0], "uv": [12, 26], "mirror": true}
]
},
{
"name": "leaf_outer_right2",
"parent": "leaf_outer_rotation_right",
"pivot": [-0.5, 14, -1],
"cubes": [
{"origin": [-3, 14, -1], "size": [5, 5, 0], "uv": [34, 20], "mirror": true}
]
},
{
"name": "leaf_outer_right3",
"parent": "leaf_outer_right2",
"pivot": [-0.5, 19, -1],
"cubes": [
{"origin": [-3, 19, -1], "size": [3, 3, 0], "uv": [56, 22], "mirror": true}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 2, 0]
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [1.75, 2, 0.75],
"cubes": [
{"origin": [1.25, 0.5, 0.25], "size": [1, 2, 1], "uv": [47, 0]}
]
},
{
"name": "foot_left",
"parent": "leg_left",
"pivot": [1.75, 1.1, 0.75],
"cubes": [
{"origin": [0.25, 0, -1.25], "size": [3, 1, 3], "uv": [38, 0]}
]
},
{
"name": "foot_left2",
"parent": "foot_left",
"pivot": [1.75, 0, -1.25],
"cubes": [
{"origin": [0.25, 0, -3.25], "size": [3, 1, 2], "uv": [36, 4]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left2",
"pivot": [2, 0.5, -2.25],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [2, 0.5, -2.25]
}
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-1.75, 2, 0.75],
"cubes": [
{"origin": [-2.25, 0.5, 0.25], "size": [1, 2, 1], "uv": [35, 0], "mirror": true}
]
},
{
"name": "foot_right",
"parent": "leg_right",
"pivot": [-1.75, 1.1, 0.75],
"cubes": [
{"origin": [-3.25, 0, -1.25], "size": [3, 1, 3], "uv": [26, 0], "mirror": true}
]
},
{
"name": "foot_right2",
"parent": "foot_right",
"pivot": [-1.75, 0, -1.25],
"cubes": [
{"origin": [-3.25, 0, -3.25], "size": [3, 1, 2], "uv": [26, 4], "mirror": true}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right2",
"pivot": [-2, 0.5, -2.25],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-2, 0.5, -2.25]
}
}
]
}
@@ -1,335 +0,0 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.unknown",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "vileplume",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "vileplume",
"pivot": [0, 7, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 2, 0],
"cubes": [
{"origin": [-5.5, 2, -4], "size": [11, 10, 8], "uv": [0, 0]}
]
},
{
"name": "mouth",
"parent": "torso",
"pivot": [0, 0, 0]
},
{
"name": "mouth_closed",
"parent": "mouth",
"pivot": [0, 5.25, -4.01],
"cubes": [
{"origin": [-2, 4.25, -4.01], "size": [4, 2, 0], "uv": [38, 60], "mirror": true}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 5.25, -3.91],
"cubes": [
{"origin": [-1, 3.75, -3.91], "size": [2, 3, 0], "uv": [29, 57], "mirror": true}
]
},
{
"name": "locator_mouth",
"parent": "mouth",
"pivot": [0, 5.25, -4],
"locators": {
"mouth": [0, 5.25, -4]
}
},
{
"name": "eyes",
"parent": "torso",
"pivot": [0, 7, -4]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.75, 7, -4.01],
"cubes": [
{"origin": [-3.25, 6.5, -4.01], "size": [1, 1, 0], "uv": [57, 62]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.75, 7, -3.41],
"cubes": [
{"origin": [-3.75, 6.5, -3.91], "size": [2, 1, 1], "inflate": 0.01, "uv": [39, 54], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2.75, 7, -4],
"locators": {
"eye1": [-2.75, 7, -4]
}
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.75, 7, -4.01],
"cubes": [
{"origin": [2.25, 6.5, -4.01], "size": [1, 1, 0], "uv": [60, 62], "mirror": true}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.75, 7, -3.41],
"cubes": [
{"origin": [1.75, 6.5, -3.91], "size": [2, 1, 1], "inflate": 0.01, "uv": [39, 57], "mirror": true}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2.75, 7, -4],
"locators": {
"eye2": [2.75, 7, -4]
}
},
{
"name": "flower",
"parent": "torso",
"pivot": [0, 12, 0],
"cubes": [
{"origin": [-3.5, 11.5, -3.5], "size": [7, 4, 7], "uv": [0, 38]},
{"origin": [-5, 11, -13.5], "size": [10, 3, 5], "uv": [34, 33]},
{"origin": [-1.5, 11, -8.5], "size": [3, 3, 5], "uv": [48, 53]},
{"origin": [5, 11, -12.5], "size": [2, 3, 4], "uv": [0, 18]},
{"origin": [-7, 11, -12.5], "size": [2, 3, 4], "uv": [0, 18], "mirror": true},
{"origin": [-11.5, 11, -8.5], "size": [10, 3, 12], "uv": [0, 18]},
{"origin": [-13.5, 11, -7.5], "size": [2, 3, 9], "uv": [42, 41], "mirror": true},
{"origin": [1.5, 11, -8.5], "size": [10, 3, 12], "uv": [0, 18], "mirror": true},
{"origin": [11.5, 11, -7.5], "size": [2, 3, 9], "uv": [42, 41]},
{"origin": [-10.5, 11, 3.5], "size": [9, 3, 9], "uv": [0, 52]},
{"origin": [-12.5, 11, 3.5], "size": [2, 3, 7], "uv": [46, 20], "mirror": true},
{"origin": [1.5, 11, 3.5], "size": [9, 3, 9], "uv": [0, 52], "mirror": true},
{"origin": [10.5, 11, 3.5], "size": [2, 3, 7], "uv": [46, 20]},
{"origin": [-1.5, 11, 3.5], "size": [3, 3, 8], "uv": [42, 9]}
]
},
{
"name": "locator_special",
"parent": "flower",
"pivot": [0, 14.5, 0],
"locators": {
"special": [0, 14.5, 0]
}
},
{
"name": "head_locators",
"parent": "torso",
"pivot": [0, 7, -4]
},
{
"name": "locator_item_face",
"parent": "head_locators",
"pivot": [0, 7, -4],
"locators": {
"item_face": [0, 7, -4]
}
},
{
"name": "locator_head",
"parent": "head_locators",
"pivot": [0, 15.5, 0],
"locators": {
"head": [0, 15.5, 0]
}
},
{
"name": "locator_item_hat",
"parent": "head_locators",
"pivot": [0, 15.5, 0],
"locators": {
"item_hat": [0, 15.5, 0]
}
},
{
"name": "locator_face",
"parent": "head_locators",
"pivot": [0, 7, -4],
"locators": {
"face": [0, 7, -4]
}
},
{
"name": "arms",
"parent": "torso",
"pivot": [0, 2, 0]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-5.5, 7, -0.5],
"cubes": [
{"origin": [-9.5, 5, -1.5], "size": [5, 2, 2], "inflate": 0.02, "uv": [30, 4], "mirror": true}
]
},
{
"name": "locator_hand_primary",
"parent": "arm_right",
"pivot": [-8.5, 6, -0.5],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-8.5, 6, -0.5],
"physical": [-8.5, 6, -0.5]
}
},
{
"name": "locator_item",
"parent": "arm_right",
"pivot": [-9.5, 6, -0.5],
"locators": {
"item": [-9.5, 6, -0.5]
}
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [5.5, 7, -0.5],
"cubes": [
{"origin": [4.5, 5, -1.5], "size": [5, 2, 2], "inflate": 0.02, "uv": [30, 4]}
]
},
{
"name": "locator_hand_secondary",
"parent": "arm_left",
"pivot": [8.5, 6, -0.5],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [8.5, 6, -0.5]
}
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 7, 0]
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-3.25, 2, 0.25],
"cubes": [
{"origin": [-4.25, 0.5, -0.75], "size": [2, 3, 2], "uv": [33, 24]}
]
},
{
"name": "foot_right",
"parent": "leg_right",
"pivot": [-3.25, 1, 0.25],
"rotation": [0, 15, 0],
"cubes": [
{"origin": [-4.75, 0, -2.25], "size": [3, 1, 4], "uv": [42, 4], "mirror": true}
]
},
{
"name": "foot_right2",
"parent": "foot_right",
"pivot": [-3.25, 0, -2.25],
"cubes": [
{"origin": [-4.75, 0, -5.25], "size": [3, 1, 3], "inflate": 0.01, "uv": [43, 0], "mirror": true}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right2",
"pivot": [-3.25, 0.5, -3.75],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-3.25, 0.5, -3.75]
}
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [3.25, 2, 0.25],
"cubes": [
{"origin": [2.25, 0.5, -0.75], "size": [2, 3, 2], "uv": [33, 19]}
]
},
{
"name": "foot_left",
"parent": "leg_left",
"pivot": [3.25, 1, 0.25],
"rotation": [0, -15, 0],
"cubes": [
{"origin": [1.75, 0, -2.25], "size": [3, 1, 4], "uv": [24, 45], "mirror": true}
]
},
{
"name": "foot_left2",
"parent": "foot_left",
"pivot": [3.25, 0, -2.25],
"cubes": [
{"origin": [1.75, 0, -5.25], "size": [3, 1, 3], "inflate": 0.01, "uv": [25, 41], "mirror": true}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left2",
"pivot": [3.25, 0.5, -3.75],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [3.25, 0.5, -3.75]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 7.25, 0],
"locators": {
"middle": [0, 7.25, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 7.25, -5],
"locators": {
"target": [0, 7.25, -5]
}
},
{
"name": "locator_root",
"parent": "vileplume",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "vileplume",
"pivot": [0, 15.5, 0],
"locators": {
"top": [0, 15.5, 0]
}
}
]
}
]
}
@@ -0,0 +1,632 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.vileplume_female",
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 4,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "vileplume",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "vileplume",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "vileplume",
"pivot": [0, 23, 0],
"locators": {
"top": [0, 23, 0]
}
},
{
"name": "body",
"parent": "vileplume",
"pivot": [0, 10, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 5.25, 0.5]
},
{
"name": "head_ai",
"parent": "torso",
"pivot": [0, 5.25, 0.5],
"cubes": [
{"origin": [-6.5, 2.75, -6.5], "size": [13, 15, 13], "inflate": 0.01, "uv": [0, 0]}
]
},
{
"name": "locator_face",
"parent": "head_ai",
"pivot": [0, 10.5, -6.5],
"locators": {
"face": [0, 10.5, -6.5]
}
},
{
"name": "locator_item_hat",
"parent": "head_ai",
"pivot": [0, 23, 0],
"locators": {
"item_hat": [0, 23, 0]
}
},
{
"name": "locator_head",
"parent": "head_ai",
"pivot": [0, 23, 0],
"locators": {
"head": [0, 23, 0]
}
},
{
"name": "locator_item_face",
"parent": "head_ai",
"pivot": [0, 11, -6.5],
"locators": {
"item_face": [0, 11, -6.5]
}
},
{
"name": "face",
"parent": "head_ai",
"pivot": [0, 10, -6.51]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 10, -6.51]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.75, 10.5, -6.51],
"cubes": [
{"origin": [2.25, 10, -6.52], "size": [1, 1, 1], "uv": [120, 17]}
]
},
{
"name": "eye_expression_left",
"parent": "eye_left",
"pivot": [2.75, 11, -6.42],
"cubes": [
{"origin": [2.25, 10.5, -6.42], "size": [1, 1, 1], "inflate": 0.01, "uv": [58, 3]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2.75, 10.5, -6.5],
"locators": {
"eye2": [2.75, 10.5, -6.5]
}
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.75, 10.5, -6.51],
"cubes": [
{"origin": [-3.25, 10, -6.52], "size": [1, 1, 1], "uv": [115, 17], "mirror": true}
]
},
{
"name": "eye_expression_right",
"parent": "eye_right",
"pivot": [-2.75, 11, -6.42],
"cubes": [
{"origin": [-3.25, 10.5, -6.42], "size": [1, 1, 1], "inflate": 0.01, "uv": [48, 3], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2.75, 10.5, -6.5],
"locators": {
"eye1": [-2.75, 10.5, -6.5]
}
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [2.75, 10.75, -5.92],
"cubes": [
{"origin": [1.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 28]}
]
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-2.75, 10.75, -5.92],
"cubes": [
{"origin": [-3.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 31], "mirror": true}
]
},
{
"name": "eyelid_happy_left",
"parent": "eyes",
"pivot": [3, 10.75, -5.92],
"cubes": [
{"origin": [1.5, 9.75, -6.41], "size": [3, 2, 1], "inflate": 0.01, "uv": [26, 52]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eyes",
"pivot": [-3, 10.75, -5.92],
"cubes": [
{"origin": [-4.5, 9.75, -6.41], "size": [3, 2, 1], "inflate": 0.01, "uv": [53, 16], "mirror": true}
]
},
{
"name": "eyelid_recoil_left",
"parent": "eyes",
"pivot": [2.75, 10.75, -5.92],
"cubes": [
{"origin": [1.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 40]}
]
},
{
"name": "eyelid_recoil_right",
"parent": "eyes",
"pivot": [-2.75, 10.75, -5.92],
"cubes": [
{"origin": [-3.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 43], "mirror": true}
]
},
{
"name": "mouth",
"parent": "face",
"pivot": [0, 8.5, -6.52]
},
{
"name": "mouth_closed",
"parent": "mouth",
"pivot": [0, 8.25, -6.52],
"cubes": [
{"origin": [-1, 7.75, -6.51], "size": [2, 1, 1], "inflate": 0.01, "uv": [54, 13]}
]
},
{
"name": "mouth_closed2",
"parent": "mouth_closed",
"pivot": [0, 8.75, -6.52],
"cubes": [
{"origin": [-2, 8.25, -6.52], "size": [1, 1, 1], "uv": [48, 0]},
{"origin": [-2, 8.25, -6.52], "size": [1, 1, 1], "uv": [48, 0]},
{"origin": [1, 8.25, -6.52], "size": [1, 1, 1], "uv": [58, 0]}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 8.25, -6.42],
"cubes": [
{"origin": [-1.5, 7.25, -6.42], "size": [3, 1, 1], "uv": [80, 13]},
{"origin": [-2, 8.25, -6.42], "size": [4, 1, 1], "uv": [80, 11]}
]
},
{
"name": "mouth_o",
"parent": "mouth",
"pivot": [0, 8.25, -6.42],
"cubes": [
{"origin": [-1, 7.25, -6.42], "size": [2, 2, 1], "uv": [80, 15]}
]
},
{
"name": "locator_mouth",
"parent": "mouth",
"pivot": [0, 8.25, -6.5],
"locators": {
"mouth": [0, 8.25, -6.5]
}
},
{
"name": "face_ditto",
"parent": "head_ai",
"pivot": [0, 7.5, -6.4]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 8.25, -6.42],
"cubes": [
{"origin": [-4.5, 7.75, -6.42], "size": [9, 1, 0], "uv": [109, 35]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 8.25, -6.32],
"cubes": [
{"origin": [-5, 7.75, -6.32], "size": [10, 1, 0], "uv": [108, 41]},
{"origin": [-4.5, 8.25, -6.33], "size": [9, 1, 0], "uv": [109, 42]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 6.5, -6.4],
"cubes": [
{"origin": [-4, 5.75, -6.42], "size": [8, 1, 0], "uv": [110, 39]},
{"origin": [-5, 6.25, -6.42], "size": [10, 1, 0], "uv": [108, 37]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 6.25, -6.31],
"cubes": [
{"origin": [-5, 5.25, -6.32], "size": [10, 2, 0], "uv": [108, 43]}
]
},
{
"name": "arms",
"parent": "head_ai",
"pivot": [0, 8.25, -1.75]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [6.5, 8.25, -1.75],
"cubes": [
{"origin": [6, 7.25, -2.75], "size": [3, 2, 2], "uv": [3, 1]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [8.85, 8.25, -0.75],
"cubes": [
{"origin": [9, 7.25, -2.75], "size": [3, 2, 2], "inflate": 0.15, "uv": [3, 9]}
]
},
{
"name": "locator_hand_secondary",
"parent": "arm_left2",
"pivot": [10.5, 8.25, -1.75],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [10.5, 8.25, -1.75]
}
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-6.5, 8.25, -1.75],
"cubes": [
{"origin": [-9, 7.25, -2.75], "size": [3, 2, 2], "uv": [3, 5], "mirror": true}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-8.85, 8.25, -0.75],
"cubes": [
{"origin": [-12, 7.25, -2.75], "size": [3, 2, 2], "inflate": 0.15, "uv": [39, 9], "mirror": true}
]
},
{
"name": "locator_hand_primary",
"parent": "arm_right2",
"pivot": [-10.5, 8.25, -1.75],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-10.5, 8.25, -1.75],
"physical": [-10.5, 8.25, -1.75]
}
},
{
"name": "locator_item",
"parent": "arm_right2",
"pivot": [-12, 8.25, -1.75],
"locators": {
"item": [-12, 8.25, -1.75]
}
},
{
"name": "flower",
"parent": "head_ai",
"pivot": [0, 15, 0]
},
{
"name": "flower_main",
"parent": "flower",
"pivot": [-0.5, 15.25, -0.5],
"cubes": [
{"origin": [-4, 20.75, -4], "size": [8, 0, 8], "uv": [100, 26]},
{"origin": [-4.5, 15.25, -4.5], "size": [9, 7, 9], "inflate": -0.1, "uv": [52, 10]},
{"origin": [-4, 20.14, -3.45], "size": [8, 2, 0], "uv": [94, 0]},
{"origin": [-4, 20.14, 3.45], "size": [8, 2, 0], "uv": [94, 2]},
{"origin": [3.45, 20.14, -3.95], "size": [0, 2, 8], "uv": [110, -8]},
{"origin": [-3.45, 20.14, -3.95], "size": [0, 2, 8], "uv": [110, -6], "mirror": true}
]
},
{
"name": "locator_special",
"parent": "flower_main",
"pivot": [0, 23, 0],
"locators": {
"special": [0, 23, 0]
}
},
{
"name": "flower_petals",
"parent": "flower_main",
"pivot": [0, 18, 0],
"rotation": [0, 10, 0]
},
{
"name": "petal_back",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, 40, 0]
},
{
"name": "petal_back_rotation",
"parent": "petal_back",
"pivot": [0, 15.5, 1.75],
"rotation": [2.5, 0, -1],
"cubes": [
{"origin": [-5, 14.25, 4.25], "size": [10, 6, 4], "inflate": 0.015, "pivot": [0, 17.25, 6.25], "rotation": [0, 180, 0], "uv": [42, 62]},
{"origin": [-5, 20.275, 4.25], "size": [10, 0, 4], "pivot": [0, 17.25, 6.25], "rotation": [0, 180, 0], "uv": [92, 91]}
]
},
{
"name": "petal_back2",
"parent": "petal_back_rotation",
"pivot": [0, 18.25, 8.25],
"cubes": [
{"origin": [-7, 14.25, 8.25], "size": [14, 6, 4], "inflate": 0.015, "pivot": [0, 17.25, 10.25], "rotation": [0, 180, 0], "uv": [46, 72]},
{"origin": [-7.5, 20.275, 8.25], "size": [13, 0, 4], "pivot": [-0.5, 17.25, 10.25], "rotation": [0, 180, 0], "uv": [80, 112]}
]
},
{
"name": "petal_back3",
"parent": "petal_back2",
"pivot": [0, 18.25, 12.25],
"cubes": [
{"origin": [-8.5, 14.25, 12.25], "size": [17, 6, 6], "inflate": 0.015, "pivot": [0, 17.25, 15.25], "rotation": [0, 180, 0], "uv": [82, 70]},
{"origin": [-8.5, 20.275, 12.25], "size": [17, 0, 6], "pivot": [0, 17.25, 15.25], "rotation": [0, 180, 0], "uv": [66, 116]}
]
},
{
"name": "petal_front_left",
"parent": "flower_petals",
"pivot": [0, 18, 0]
},
{
"name": "petal_front_left_rotation",
"parent": "petal_front_left",
"pivot": [0, 15.5, -1.75],
"rotation": [-2.5, 0, 1],
"cubes": [
{"origin": [-7, 14.25, -8], "size": [14, 6, 4], "inflate": 0.01, "uv": [62, 0]},
{"origin": [-7, 20.27, -8], "size": [14, 0, 4], "uv": [42, 93]}
]
},
{
"name": "petal_front_left2",
"parent": "petal_front_left_rotation",
"pivot": [0, 17.25, -8],
"cubes": [
{"origin": [-10.5, 14.25, -12], "size": [21, 6, 4], "inflate": 0.01, "uv": [58, 26]},
{"origin": [-10.5, 20.27, -12], "size": [21, 0, 4], "uv": [42, 97]}
]
},
{
"name": "petal_front_left3",
"parent": "petal_front_left2",
"pivot": [0, 20.25, -12],
"cubes": [
{"origin": [-11.5, 14.25, -18], "size": [23, 6, 6], "inflate": 0.01, "uv": [0, 28]},
{"origin": [-11.5, 20.27, -18], "size": [23, 0, 6], "uv": [28, 102]}
]
},
{
"name": "petal_back_left",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, -80, 0]
},
{
"name": "petal_back_left_rotation",
"parent": "petal_back_left",
"pivot": [0, 15, -1.75],
"rotation": [-2.5, 0, 1],
"cubes": [
{"origin": [-6.5, 14.25, -8.25], "size": [11, 6, 4], "uv": [88, 16]},
{"origin": [-6.5, 20.26, -8.25], "size": [11, 0, 4], "uv": [102, 87]}
]
},
{
"name": "petal_back_left2",
"parent": "petal_back_left_rotation",
"pivot": [0, 18.25, -8.25],
"cubes": [
{"origin": [-10, 14.25, -12.25], "size": [17, 6, 4], "uv": [30, 52]},
{"origin": [-10, 20.26, -12.25], "size": [17, 0, 4], "uv": [34, 114]}
]
},
{
"name": "petal_back_left3",
"parent": "petal_back_left2",
"pivot": [0, 20.25, -12.25],
"cubes": [
{"origin": [-11, 14.25, -18.25], "size": [19, 6, 6], "uv": [72, 46]},
{"origin": [-11, 20.26, -18.25], "size": [19, 0, 6], "uv": [36, 122]}
]
},
{
"name": "petal_front_right",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, 80, 0]
},
{
"name": "petal_front_right_rotation",
"parent": "petal_front_right",
"pivot": [0, 15.5, -0.75],
"rotation": [-2.5, 0, 0.5],
"cubes": [
{"origin": [-7, 14.25, -8], "size": [13, 6, 4], "uv": [94, 6], "mirror": true},
{"origin": [-7, 20.26, -8], "size": [13, 0, 4], "uv": [76, 87], "mirror": true}
]
},
{
"name": "petal_front_right2",
"parent": "petal_front_right_rotation",
"pivot": [0, 17.25, -8],
"cubes": [
{"origin": [-10.5, 14.25, -12], "size": [21, 6, 4], "uv": [54, 36], "mirror": true},
{"origin": [-10.5, 20.26, -12], "size": [21, 0, 4], "uv": [-4, 122], "mirror": true}
]
},
{
"name": "petal_front_right3",
"parent": "petal_front_right2",
"pivot": [0, 20.25, -12],
"cubes": [
{"origin": [-11.5, 14.25, -18], "size": [23, 6, 6], "uv": [0, 40], "mirror": true},
{"origin": [-11.5, 20.26, -18], "size": [23, 0, 6], "uv": [32, 108], "mirror": true}
]
},
{
"name": "petal_back_right",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, 160, 0]
},
{
"name": "petal_back_right_rotation",
"parent": "petal_back_right",
"pivot": [0, 15.5, -1.75],
"rotation": [-2.5, 0, 1],
"cubes": [
{"origin": [-4.5, 14.25, -8.25], "size": [11, 6, 4], "inflate": 0.01, "uv": [0, 52], "mirror": true},
{"origin": [-4.5, 20.27, -8.25], "size": [11, 0, 4], "uv": [70, 93], "mirror": true}
]
},
{
"name": "petal_back_right2",
"parent": "petal_back_right_rotation",
"pivot": [0, 18.25, -8.25],
"cubes": [
{"origin": [-7, 14.25, -12.25], "size": [17, 6, 4], "inflate": 0.01, "uv": [0, 62], "mirror": true},
{"origin": [-7, 20.27, -12.25], "size": [17, 0, 4], "uv": [34, 118], "mirror": true}
]
},
{
"name": "petal_back_right3",
"parent": "petal_back_right2",
"pivot": [0, 18.25, -12.25],
"cubes": [
{"origin": [-8, 14.25, -18.25], "size": [19, 6, 6], "inflate": 0.01, "uv": [72, 58], "mirror": true},
{"origin": [-8, 20.27, -18.25], "size": [19, 0, 6], "uv": [74, 122], "mirror": true}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 3.25, 0.75]
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [2.6, 2.75, 1],
"cubes": [
{"origin": [2.1, 1.5, 0.5], "size": [1, 2, 1], "inflate": 0.1, "uv": [40, 1]}
]
},
{
"name": "foot_left",
"parent": "leg_left",
"pivot": [2.6, 2, 1],
"cubes": [
{"origin": [1.6, -0.1, -3], "size": [2, 2, 5], "inflate": -0.1, "uv": [39, 2]}
]
},
{
"name": "foot_left2",
"parent": "foot_left",
"pivot": [2.6, 0, -2.9],
"cubes": [
{"origin": [1.6, 0, -6.85], "size": [2, 2, 4], "inflate": 0.01, "uv": [58, 46]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left2",
"pivot": [2.6, 1, -5.35],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [2.6, 1, -5.35]
}
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-2.6, 2.75, 1],
"cubes": [
{"origin": [-3.1, 1.5, 0.5], "size": [1, 2, 1], "inflate": 0.1, "uv": [40, 4], "mirror": true}
]
},
{
"name": "foot_right",
"parent": "leg_right",
"pivot": [-2.6, 2, 1],
"cubes": [
{"origin": [-3.6, -0.1, -3], "size": [2, 2, 5], "inflate": -0.1, "uv": [48, 0], "mirror": true}
]
},
{
"name": "foot_right2",
"parent": "foot_right",
"pivot": [-2.6, 0, -2.9],
"cubes": [
{"origin": [-3.6, 0, -6.85], "size": [2, 2, 4], "inflate": 0.01, "uv": [49, 7], "mirror": true}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right2",
"pivot": [-2.6, 1, -5.35],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-2.6, 1, -5.35]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 10.75, 0],
"locators": {
"middle": [0, 10.75, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 9, -9],
"locators": {
"target": [0, 9, -9]
}
}
]
}
]
}
@@ -0,0 +1,632 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.vileplume_male",
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 4,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "vileplume",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "vileplume",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "vileplume",
"pivot": [0, 23, 0],
"locators": {
"top": [0, 23, 0]
}
},
{
"name": "body",
"parent": "vileplume",
"pivot": [0, 10, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 5.25, 0.5]
},
{
"name": "head_ai",
"parent": "torso",
"pivot": [0, 5.25, 0.5],
"cubes": [
{"origin": [-6.5, 2.75, -6.5], "size": [13, 15, 13], "inflate": 0.01, "uv": [0, 0]}
]
},
{
"name": "locator_face",
"parent": "head_ai",
"pivot": [0, 10.5, -6.5],
"locators": {
"face": [0, 10.5, -6.5]
}
},
{
"name": "locator_item_hat",
"parent": "head_ai",
"pivot": [0, 23, 0],
"locators": {
"item_hat": [0, 23, 0]
}
},
{
"name": "locator_head",
"parent": "head_ai",
"pivot": [0, 23, 0],
"locators": {
"head": [0, 23, 0]
}
},
{
"name": "locator_item_face",
"parent": "head_ai",
"pivot": [0, 11, -6.5],
"locators": {
"item_face": [0, 11, -6.5]
}
},
{
"name": "face",
"parent": "head_ai",
"pivot": [0, 10, -6.51]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 10, -6.51]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.75, 10.5, -6.51],
"cubes": [
{"origin": [2.25, 10, -6.52], "size": [1, 1, 1], "uv": [120, 17]}
]
},
{
"name": "eye_expression_left",
"parent": "eye_left",
"pivot": [2.75, 11, -6.42],
"cubes": [
{"origin": [2.25, 10.5, -6.42], "size": [1, 1, 1], "inflate": 0.01, "uv": [58, 3]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2.75, 10.5, -6.5],
"locators": {
"eye2": [2.75, 10.5, -6.5]
}
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.75, 10.5, -6.51],
"cubes": [
{"origin": [-3.25, 10, -6.52], "size": [1, 1, 1], "uv": [115, 17], "mirror": true}
]
},
{
"name": "eye_expression_right",
"parent": "eye_right",
"pivot": [-2.75, 11, -6.42],
"cubes": [
{"origin": [-3.25, 10.5, -6.42], "size": [1, 1, 1], "inflate": 0.01, "uv": [48, 3], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2.75, 10.5, -6.5],
"locators": {
"eye1": [-2.75, 10.5, -6.5]
}
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [2.75, 10.75, -5.92],
"cubes": [
{"origin": [1.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 28]}
]
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-2.75, 10.75, -5.92],
"cubes": [
{"origin": [-3.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 31], "mirror": true}
]
},
{
"name": "eyelid_happy_left",
"parent": "eyes",
"pivot": [3, 10.75, -5.92],
"cubes": [
{"origin": [1.5, 9.75, -6.41], "size": [3, 2, 1], "inflate": 0.01, "uv": [26, 52]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eyes",
"pivot": [-3, 10.75, -5.92],
"cubes": [
{"origin": [-4.5, 9.75, -6.41], "size": [3, 2, 1], "inflate": 0.01, "uv": [53, 16], "mirror": true}
]
},
{
"name": "eyelid_recoil_left",
"parent": "eyes",
"pivot": [2.75, 10.75, -5.92],
"cubes": [
{"origin": [1.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 40]}
]
},
{
"name": "eyelid_recoil_right",
"parent": "eyes",
"pivot": [-2.75, 10.75, -5.92],
"cubes": [
{"origin": [-3.75, 9.75, -6.41], "size": [2, 2, 1], "inflate": 0.01, "uv": [0, 43], "mirror": true}
]
},
{
"name": "mouth",
"parent": "face",
"pivot": [0, 8.5, -6.52]
},
{
"name": "mouth_closed",
"parent": "mouth",
"pivot": [0, 8.25, -6.52],
"cubes": [
{"origin": [-1, 7.75, -6.51], "size": [2, 1, 1], "inflate": 0.01, "uv": [54, 13]}
]
},
{
"name": "mouth_closed2",
"parent": "mouth_closed",
"pivot": [0, 8.75, -6.52],
"cubes": [
{"origin": [-2, 8.25, -6.52], "size": [1, 1, 1], "uv": [48, 0]},
{"origin": [-2, 8.25, -6.52], "size": [1, 1, 1], "uv": [48, 0]},
{"origin": [1, 8.25, -6.52], "size": [1, 1, 1], "uv": [58, 0]}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 8.25, -6.42],
"cubes": [
{"origin": [-1.5, 7.25, -6.42], "size": [3, 1, 1], "uv": [80, 13]},
{"origin": [-2, 8.25, -6.42], "size": [4, 1, 1], "uv": [80, 11]}
]
},
{
"name": "mouth_o",
"parent": "mouth",
"pivot": [0, 8.25, -6.42],
"cubes": [
{"origin": [-1, 7.25, -6.42], "size": [2, 2, 1], "uv": [80, 15]}
]
},
{
"name": "locator_mouth",
"parent": "mouth",
"pivot": [0, 8.25, -6.5],
"locators": {
"mouth": [0, 8.25, -6.5]
}
},
{
"name": "face_ditto",
"parent": "head_ai",
"pivot": [0, 7.5, -6.4]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 8.25, -6.42],
"cubes": [
{"origin": [-4.5, 7.75, -6.42], "size": [9, 1, 0], "uv": [109, 35]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 8.25, -6.32],
"cubes": [
{"origin": [-5, 7.75, -6.32], "size": [10, 1, 0], "uv": [108, 41]},
{"origin": [-4.5, 8.25, -6.33], "size": [9, 1, 0], "uv": [109, 42]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 6.5, -6.4],
"cubes": [
{"origin": [-4, 5.75, -6.42], "size": [8, 1, 0], "uv": [110, 39]},
{"origin": [-5, 6.25, -6.42], "size": [10, 1, 0], "uv": [108, 37]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 6.25, -6.31],
"cubes": [
{"origin": [-5, 5.25, -6.32], "size": [10, 2, 0], "uv": [108, 43]}
]
},
{
"name": "arms",
"parent": "head_ai",
"pivot": [0, 8.25, -1.75]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [6.5, 8.25, -1.75],
"cubes": [
{"origin": [6, 7.25, -2.75], "size": [3, 2, 2], "uv": [3, 1]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [8.85, 8.25, -0.75],
"cubes": [
{"origin": [9, 7.25, -2.75], "size": [3, 2, 2], "inflate": 0.15, "uv": [3, 9]}
]
},
{
"name": "locator_hand_secondary",
"parent": "arm_left2",
"pivot": [10.5, 8.25, -1.75],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [10.5, 8.25, -1.75]
}
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-6.5, 8.25, -1.75],
"cubes": [
{"origin": [-9, 7.25, -2.75], "size": [3, 2, 2], "uv": [3, 5], "mirror": true}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-8.85, 8.25, -0.75],
"cubes": [
{"origin": [-12, 7.25, -2.75], "size": [3, 2, 2], "inflate": 0.15, "uv": [39, 9], "mirror": true}
]
},
{
"name": "locator_hand_primary",
"parent": "arm_right2",
"pivot": [-10.5, 8.25, -1.75],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-10.5, 8.25, -1.75],
"physical": [-10.5, 8.25, -1.75]
}
},
{
"name": "locator_item",
"parent": "arm_right2",
"pivot": [-12, 8.25, -1.75],
"locators": {
"item": [-12, 8.25, -1.75]
}
},
{
"name": "flower",
"parent": "head_ai",
"pivot": [0, 15, 0]
},
{
"name": "flower_main",
"parent": "flower",
"pivot": [-0.5, 15.25, -0.5],
"cubes": [
{"origin": [-4, 20.75, -4], "size": [8, 0, 8], "uv": [100, 26]},
{"origin": [-4.5, 15.25, -4.5], "size": [9, 7, 9], "inflate": -0.1, "uv": [52, 10]},
{"origin": [-4, 20.14, -3.45], "size": [8, 2, 0], "uv": [94, 0]},
{"origin": [-4, 20.14, 3.45], "size": [8, 2, 0], "uv": [94, 2]},
{"origin": [3.45, 20.14, -3.95], "size": [0, 2, 8], "uv": [110, -8]},
{"origin": [-3.45, 20.14, -3.95], "size": [0, 2, 8], "uv": [110, -6], "mirror": true}
]
},
{
"name": "locator_special",
"parent": "flower_main",
"pivot": [0, 23, 0],
"locators": {
"special": [0, 23, 0]
}
},
{
"name": "flower_petals",
"parent": "flower_main",
"pivot": [0, 18, 0],
"rotation": [0, 10, 0]
},
{
"name": "petal_back",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, 40, 0]
},
{
"name": "petal_back_rotation",
"parent": "petal_back",
"pivot": [0, 15.5, 1.75],
"rotation": [2.5, 0, -1],
"cubes": [
{"origin": [-5, 14.25, 4.25], "size": [10, 6, 4], "inflate": 0.015, "pivot": [0, 17.25, 6.25], "rotation": [0, 180, 0], "uv": [42, 62]},
{"origin": [-5, 20.275, 4.25], "size": [10, 0, 4], "pivot": [0, 17.25, 6.25], "rotation": [0, 180, 0], "uv": [-4, 77]}
]
},
{
"name": "petal_back2",
"parent": "petal_back_rotation",
"pivot": [0, 18.25, 8.25],
"cubes": [
{"origin": [-7, 14.25, 8.25], "size": [14, 6, 4], "inflate": 0.015, "pivot": [0, 17.25, 10.25], "rotation": [0, 180, 0], "uv": [46, 72]},
{"origin": [-7, 20.275, 8.25], "size": [14, 0, 4], "pivot": [0, 17.25, 10.25], "rotation": [0, 180, 0], "uv": [82, 83]}
]
},
{
"name": "petal_back3",
"parent": "petal_back2",
"pivot": [0, 18.25, 12.25],
"cubes": [
{"origin": [-8.5, 14.25, 12.25], "size": [17, 6, 6], "inflate": 0.015, "pivot": [0, 17.25, 15.25], "rotation": [0, 180, 0], "uv": [82, 70]},
{"origin": [-8.5, 20.275, 12.25], "size": [17, 0, 6], "pivot": [0, 17.25, 15.25], "rotation": [0, 180, 0], "uv": [40, 87]}
]
},
{
"name": "petal_front_left",
"parent": "flower_petals",
"pivot": [0, 18, 0]
},
{
"name": "petal_front_left_rotation",
"parent": "petal_front_left",
"pivot": [0, 15.5, -1.75],
"rotation": [-2.5, 0, 1],
"cubes": [
{"origin": [-7, 14.25, -8], "size": [14, 6, 4], "inflate": 0.01, "uv": [62, 0]},
{"origin": [-7, 20.27, -8], "size": [14, 0, 4], "uv": [-4, 73]}
]
},
{
"name": "petal_front_left2",
"parent": "petal_front_left_rotation",
"pivot": [0, 17.25, -8],
"cubes": [
{"origin": [-10.5, 14.25, -12], "size": [21, 6, 4], "inflate": 0.01, "uv": [58, 26]},
{"origin": [-10.5, 20.27, -12], "size": [21, 0, 4], "uv": [-4, 82]}
]
},
{
"name": "petal_front_left3",
"parent": "petal_front_left2",
"pivot": [0, 20.25, -12],
"cubes": [
{"origin": [-11.5, 14.25, -18], "size": [23, 6, 6], "inflate": 0.01, "uv": [0, 28]},
{"origin": [-11.5, 20.27, -18], "size": [23, 0, 6], "uv": [-6, 90]}
]
},
{
"name": "petal_back_left",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, -80, 0]
},
{
"name": "petal_back_left_rotation",
"parent": "petal_back_left",
"pivot": [0, 15, -1.75],
"rotation": [-2.5, 0, 1],
"cubes": [
{"origin": [-6.5, 14.25, -8.25], "size": [11, 6, 4], "uv": [88, 16]},
{"origin": [-6.5, 20.26, -8.25], "size": [11, 0, 4], "uv": [60, 83]}
]
},
{
"name": "petal_back_left2",
"parent": "petal_back_left_rotation",
"pivot": [0, 18.25, -8.25],
"cubes": [
{"origin": [-10, 14.25, -12.25], "size": [17, 6, 4], "uv": [30, 52]},
{"origin": [-10, 20.26, -12.25], "size": [17, 0, 4], "uv": [-4, 102]}
]
},
{
"name": "petal_back_left3",
"parent": "petal_back_left2",
"pivot": [0, 20.25, -12.25],
"cubes": [
{"origin": [-11, 14.25, -18.25], "size": [19, 6, 6], "uv": [72, 46]},
{"origin": [-11, 20.26, -18.25], "size": [19, 0, 6], "uv": [-6, 110]}
]
},
{
"name": "petal_front_right",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, 80, 0]
},
{
"name": "petal_front_right_rotation",
"parent": "petal_front_right",
"pivot": [0, 15.5, -0.75],
"rotation": [-2.5, 0, 0.5],
"cubes": [
{"origin": [-7, 14.25, -8], "size": [13, 6, 4], "uv": [94, 6], "mirror": true},
{"origin": [-7, 20.26, -8], "size": [13, 0, 4], "uv": [16, 77], "mirror": true}
]
},
{
"name": "petal_front_right2",
"parent": "petal_front_right_rotation",
"pivot": [0, 17.25, -8],
"cubes": [
{"origin": [-10.5, 14.25, -12], "size": [21, 6, 4], "uv": [54, 36], "mirror": true},
{"origin": [-10.5, 20.26, -12], "size": [21, 0, 4], "uv": [-4, 86], "mirror": true}
]
},
{
"name": "petal_front_right3",
"parent": "petal_front_right2",
"pivot": [0, 20.25, -12],
"cubes": [
{"origin": [-11.5, 14.25, -18], "size": [23, 6, 6], "uv": [0, 40], "mirror": true},
{"origin": [-11.5, 20.26, -18], "size": [23, 0, 6], "uv": [-6, 96], "mirror": true}
]
},
{
"name": "petal_back_right",
"parent": "flower_petals",
"pivot": [0, 18, 0],
"rotation": [0, 160, 0]
},
{
"name": "petal_back_right_rotation",
"parent": "petal_back_right",
"pivot": [0, 15.5, -1.75],
"rotation": [-2.5, 0, 1],
"cubes": [
{"origin": [-4.5, 14.25, -8.25], "size": [11, 6, 4], "inflate": 0.01, "uv": [0, 52], "mirror": true},
{"origin": [-4.5, 20.27, -8.25], "size": [11, 0, 4], "uv": [38, 83], "mirror": true}
]
},
{
"name": "petal_back_right2",
"parent": "petal_back_right_rotation",
"pivot": [0, 18.25, -8.25],
"cubes": [
{"origin": [-7, 14.25, -12.25], "size": [17, 6, 4], "inflate": 0.01, "uv": [0, 62], "mirror": true},
{"origin": [-7, 20.27, -12.25], "size": [17, 0, 4], "uv": [-4, 106], "mirror": true}
]
},
{
"name": "petal_back_right3",
"parent": "petal_back_right2",
"pivot": [0, 18.25, -12.25],
"cubes": [
{"origin": [-8, 14.25, -18.25], "size": [19, 6, 6], "inflate": 0.01, "uv": [72, 58], "mirror": true},
{"origin": [-8, 20.27, -18.25], "size": [19, 0, 6], "uv": [-6, 116], "mirror": true}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 3.25, 0.75]
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [2.6, 2.75, 1],
"cubes": [
{"origin": [2.1, 1.5, 0.5], "size": [1, 2, 1], "inflate": 0.1, "uv": [40, 1]}
]
},
{
"name": "foot_left",
"parent": "leg_left",
"pivot": [2.6, 2, 1],
"cubes": [
{"origin": [1.6, -0.1, -3], "size": [2, 2, 5], "inflate": -0.1, "uv": [39, 2]}
]
},
{
"name": "foot_left2",
"parent": "foot_left",
"pivot": [2.6, 0, -2.9],
"cubes": [
{"origin": [1.6, 0, -6.85], "size": [2, 2, 4], "inflate": 0.01, "uv": [58, 46]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left2",
"pivot": [2.6, 1, -5.35],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [2.6, 1, -5.35]
}
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-2.6, 2.75, 1],
"cubes": [
{"origin": [-3.1, 1.5, 0.5], "size": [1, 2, 1], "inflate": 0.1, "uv": [40, 4], "mirror": true}
]
},
{
"name": "foot_right",
"parent": "leg_right",
"pivot": [-2.6, 2, 1],
"cubes": [
{"origin": [-3.6, -0.1, -3], "size": [2, 2, 5], "inflate": -0.1, "uv": [48, 0], "mirror": true}
]
},
{
"name": "foot_right2",
"parent": "foot_right",
"pivot": [-2.6, 0, -2.9],
"cubes": [
{"origin": [-3.6, 0, -6.85], "size": [2, 2, 4], "inflate": 0.01, "uv": [49, 7], "mirror": true}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right2",
"pivot": [-2.6, 1, -5.35],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-2.6, 1, -5.35]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 10.75, 0],
"locators": {
"middle": [0, 10.75, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 9, -9],
"locators": {
"target": [0, 9, -9]
}
}
]
}
]
}
@@ -5,7 +5,7 @@
"description": {
"identifier": "geometry.poliwag",
"texture_width": 64,
"texture_height": 32,
"texture_height": 64,
"visible_bounds_width": 4,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
@@ -13,250 +13,7 @@
"bones": [
{
"name": "poliwag",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "poliwag",
"pivot": [0, 7, 0.25]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 3, 1],
"cubes": [
{"origin": [-5, 2, -3.75], "size": [10, 10, 8], "uv": [0, 0]},
{"origin": [-3.5, 2, -3.751], "size": [7, 5, 0], "uv": [36, 14]},
{"origin": [-1.5, 7.5, -4.5], "size": [3, 2, 1], "pivot": [0, 8.375, -4.4125], "rotation": [-2.5, 0, 0], "uv": [0, 0]},
{"origin": [-1, 8.25, -4.501], "size": [2, 1, 0], "pivot": [0, 8.375, -4.4125], "rotation": [-2.5, 0, 0], "uv": [29, 6]}
]
},
{
"name": "locator_item",
"parent": "torso",
"pivot": [0, 12, 0.25],
"locators": {
"item": [0, 12, 0.25]
}
},
{
"name": "locator_item_face",
"parent": "torso",
"pivot": [0, 10.6, -3.75],
"locators": {
"item_face": [0, 10.6, -3.75]
}
},
{
"name": "locator_face",
"parent": "torso",
"pivot": [0, 10.25, -4.3],
"locators": {
"face": [0, 10.25, -4.3]
}
},
{
"name": "locator_item_hat",
"parent": "torso",
"pivot": [0, 12, 0.25],
"locators": {
"item_hat": [0, 12, 0.25]
}
},
{
"name": "locator_head",
"parent": "torso",
"pivot": [0, 12, -1],
"locators": {
"head": [0, 12, -1]
}
},
{
"name": "locator_mouth",
"parent": "torso",
"pivot": [0, 8.75, -4.5],
"locators": {
"mouth": [0, 8.75, -4.5],
"special": [0, 8.75, -4.5]
}
},
{
"name": "eyes",
"parent": "torso",
"pivot": [0, 10.275, -3.775]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.75, 10.275, -3.775],
"cubes": [
{"origin": [1.25, 8.775, -3.751], "size": [3, 3, 0], "pivot": [2.75, 10.275, -3.775], "rotation": [0, 0, -2.5], "uv": [58, 14]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2.25, 10.6, -3.75],
"locators": {
"eye2": [2.25, 10.6, -3.75]
}
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.75, 10.275, -3.775],
"cubes": [
{"origin": [1.25, 8.775, -3.651], "size": [3, 3, 1], "inflate": 0.01, "pivot": [2.75, 10.275, -3.175], "rotation": [0, 0, -2.5], "uv": [0, 18]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.75, 10.275, -3.775],
"cubes": [
{"origin": [-4.25, 8.775, -3.751], "size": [3, 3, 0], "pivot": [-2.75, 10.275, -3.775], "rotation": [0, 0, 2.5], "uv": [58, 17], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2.25, 10.6, -3.75],
"locators": {
"eye1": [-2.25, 10.6, -3.75]
}
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.75, 10.275, -3.775],
"cubes": [
{"origin": [-4.25, 8.775, -3.651], "size": [3, 3, 1], "inflate": 0.01, "pivot": [-2.75, 10.275, -3.175], "rotation": [0, 0, 2.5], "uv": [8, 18], "mirror": true}
]
},
{
"name": "tail1",
"parent": "torso",
"pivot": [0, 2.75, 4.25],
"cubes": [
{"origin": [-2.5, 2.75, 4.25], "size": [5, 0, 5], "uv": [48, 9]}
]
},
{
"name": "tail2",
"parent": "tail1",
"pivot": [0, 2.75, 9.25],
"cubes": [
{"origin": [-3.5, 2.75, 9.25], "size": [7, 0, 5], "uv": [45, 4]}
]
},
{
"name": "locator_tail",
"parent": "tail2",
"pivot": [0, 2.75, 11.75],
"rotation": [0, 180, 0],
"locators": {
"tail": [0, 2.75, 11.75],
"physical": [0, 2.75, 11.75]
}
},
{
"name": "tail3",
"parent": "tail2",
"pivot": [0, 2.75, 14.25],
"cubes": [
{"origin": [-3.5, 2.75, 14.25], "size": [7, 0, 4], "uv": [46, 0]}
]
},
{
"name": "locator_tail_tip",
"parent": "tail3",
"pivot": [0, 3, 19],
"rotation": [0, 180, 0],
"locators": {
"tail_tip": [0, 2.75, 19.75]
}
},
{
"name": "leg_right",
"parent": "body",
"pivot": [-2.25, 2, 1.25],
"rotation": [0, 10, 0],
"cubes": [
{"origin": [-2.75, 0.5, 0.25], "size": [1, 3, 2], "uv": [0, 3]}
]
},
{
"name": "foot_right1",
"parent": "leg_right",
"pivot": [-2.25, 1, 1.25],
"cubes": [
{"origin": [-3.75, 0, -1.25], "size": [3, 1, 4], "inflate": 0.01, "uv": [36, 5]}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right1",
"pivot": [-2.25, 0.5, 0],
"locators": {
"foot_primary": [-2.25, 0.5, 0]
}
},
{
"name": "foot_right2",
"parent": "foot_right1",
"pivot": [-2.25, 0, -1.25],
"cubes": [
{"origin": [-3.75, 0, -4.25], "size": [3, 1, 3], "uv": [38, 0]}
]
},
{
"name": "leg_left",
"parent": "body",
"pivot": [2.25, 2, 1.25],
"rotation": [0, -10, 0],
"cubes": [
{"origin": [1.75, 0.5, 0.25], "size": [1, 3, 2], "uv": [50, 14]}
]
},
{
"name": "foot_left1",
"parent": "leg_left",
"pivot": [2.25, 1, 1.25],
"cubes": [
{"origin": [0.75, 0, -1.25], "size": [3, 1, 4], "inflate": 0.01, "uv": [28, 0]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left1",
"pivot": [2.25, 0.5, 0],
"locators": {
"foot_secondary": [2.25, 0.5, 0]
}
},
{
"name": "foot_left2",
"parent": "foot_left1",
"pivot": [2.25, 0, -1.25],
"cubes": [
{"origin": [0.75, 0, -4.25], "size": [3, 1, 3], "uv": [36, 10]}
]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 5, -6.75],
"locators": {
"target": [0, 5, -6.75]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 6.75, 0],
"locators": {
"middle": [0, 6.75, 0]
}
"pivot": [0, -0.5, 0]
},
{
"name": "locator_root",
@@ -269,9 +26,315 @@
{
"name": "locator_top",
"parent": "poliwag",
"pivot": [0, 12.25, 2.75],
"pivot": [0, 12.5, 0],
"locators": {
"top": [0, 12.25, 2.75]
"top": [0, 12.5, 0]
}
},
{
"name": "body",
"parent": "poliwag",
"pivot": [0, -0.5, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 7, -6],
"locators": {
"target": [0, 7, -6]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 7, 0],
"locators": {
"middle": [0, 7, 0]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 5.25, 0],
"cubes": [
{"origin": [-5, 2, -4.5], "size": [10, 10, 9], "uv": [0, 0]}
]
},
{
"name": "mouth",
"parent": "torso",
"pivot": [0, 8.25, -4.5],
"cubes": [
{"origin": [-1.5, 7.25, -5.5], "size": [3, 2, 2], "uv": [0, 30]},
{"origin": [-1, 7.75, -5.51], "size": [2, 1, 0], "uv": [0, 8]}
]
},
{
"name": "mouth_open",
"parent": "torso",
"pivot": [0, 8.25, -2.5],
"cubes": [
{"origin": [-1.5, 6.5, -3.5], "size": [3, 3, 2], "uv": [29, 4]},
{"origin": [-1, 7, -3.51], "size": [2, 2, 0], "uv": [4, 3]}
]
},
{
"name": "eyes",
"parent": "torso",
"pivot": [-0.05, 8.5, -4.5]
},
{
"name": "left_eye",
"parent": "eyes",
"pivot": [2.95, 10, -4.5],
"cubes": [
{"origin": [1.45, 8.5, -4.51], "size": [3, 3, 0], "uv": [22, 31]}
]
},
{
"name": "left_pupil",
"parent": "eyes",
"pivot": [2.95, 10, -1.5],
"cubes": [
{"origin": [1.45, 8.5, -4.52], "size": [2, 3, 0], "uv": [0, 26]}
]
},
{
"name": "locator_eye_left",
"parent": "left_pupil",
"pivot": [2.75, 10, -4.52],
"locators": {
"eye2": [2.75, 10, -4.52]
}
},
{
"name": "right_eye",
"parent": "eyes",
"pivot": [-2.95, 10, -4.5],
"cubes": [
{"origin": [-4.45, 8.5, -4.51], "size": [3, 3, 0], "uv": [16, 30]}
]
},
{
"name": "right_pupil",
"parent": "right_eye",
"pivot": [-2.95, 10, -4.5],
"cubes": [
{"origin": [-3.45, 8.5, -4.52], "size": [2, 3, 0], "uv": [0, 23]}
]
},
{
"name": "locator_eye_right",
"parent": "right_pupil",
"pivot": [-2.75, 10, -4.52],
"locators": {
"eye1": [-2.75, 10, -4.52]
}
},
{
"name": "eyelids",
"parent": "eyes",
"pivot": [-0.05, 8.5, -4.65]
},
{
"name": "left_eyelid",
"parent": "eyelids",
"pivot": [2.95, 10, -4.4],
"cubes": [
{"origin": [1.7, 9.5, -4.41], "size": [2, 1, 0], "inflate": 0.01, "uv": [4, 7]}
]
},
{
"name": "right_eyelid",
"parent": "eyelids",
"pivot": [-2.95, 10, -4.4],
"cubes": [
{"origin": [-3.7, 9.5, -4.41], "size": [2, 1, 0], "inflate": 0.01, "uv": [0, 7]}
]
},
{
"name": "eyelids2",
"parent": "eyes",
"pivot": [-0.05, 8.5, -4.65]
},
{
"name": "left_eyelid2",
"parent": "eyelids2",
"pivot": [2.7, 9, -4.4],
"cubes": [
{"origin": [1.45, 8.5, -4.41], "size": [3, 3, 0], "inflate": 0.02, "uv": [10, 30]}
]
},
{
"name": "right_eyelid2",
"parent": "eyelids2",
"pivot": [-2.7, 9, -4.4],
"cubes": [
{"origin": [-4.45, 8.5, -4.41], "size": [3, 3, 0], "inflate": 0.02, "uv": [10, 25]}
]
},
{
"name": "tail",
"parent": "torso",
"pivot": [0, 3, 4.5],
"cubes": [
{"origin": [-2.5, 3, 6.5], "size": [5, 0, 3], "uv": [21, 24]},
{"origin": [-1, 3, 3.5], "size": [2, 0, 3], "uv": [0, 0]}
]
},
{
"name": "tail2",
"parent": "tail",
"pivot": [0, 3, 9.5],
"cubes": [
{"origin": [-4.5, 3, 9.5], "size": [9, 0, 5], "uv": [19, 19]}
]
},
{
"name": "locator_tail",
"parent": "tail2",
"pivot": [0, 3, 12.5],
"rotation": [-180, 0, 180],
"locators": {
"tail": [0, 3, 12.5]
}
},
{
"name": "tail3",
"parent": "tail2",
"pivot": [0, 3, 14.5],
"cubes": [
{"origin": [-4.5, 3, 14.5], "size": [9, 0, 6], "uv": [0, 19]}
]
},
{
"name": "locator_tail_tip",
"parent": "tail3",
"pivot": [0, 3, 19.5],
"rotation": [-180, 0, 180],
"locators": {
"tail_tip": [0, 3, 19.5]
}
},
{
"name": "locator_face",
"parent": "torso",
"pivot": [0, 9.25, -4.5],
"locators": {
"face": [0, 9.25, -4.5]
}
},
{
"name": "locator_mouth",
"parent": "torso",
"pivot": [0, 8.25, -5.5],
"locators": {
"mouth": [0, 8.25, -5.5],
"special": [0, 8.25, -5.5]
}
},
{
"name": "locator_head",
"parent": "torso",
"pivot": [0, 12, -2],
"locators": {
"head": [0, 12, -2],
"physical": [0, 12, -2]
}
},
{
"name": "item_hat",
"parent": "torso",
"pivot": [0, 12, 0],
"locators": {
"item_hat": [0, 12, 0]
}
},
{
"name": "locator_item_face",
"parent": "torso",
"pivot": [0, 9.25, -4.5],
"locators": {
"item_face": [0, 9.25, -4.5]
}
},
{
"name": "locator_item",
"parent": "torso",
"pivot": [0, 12, 0],
"locators": {
"item": [0, 12, 0]
}
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 2.5, 0]
},
{
"name": "left_leg",
"parent": "legs",
"pivot": [2.5, 2, 0.25],
"cubes": [
{"origin": [2, 0.5, -0.75], "size": [1, 2, 2], "uv": [0, 19]}
]
},
{
"name": "left_foot",
"parent": "left_leg",
"pivot": [2.5, 1, 0.25],
"cubes": [
{"origin": [1, 0, -1.75], "size": [3, 1, 4], "uv": [14, 25]}
]
},
{
"name": "left_toe",
"parent": "left_foot",
"pivot": [2.5, 0, -1.75],
"cubes": [
{"origin": [1, 0, -4.75], "size": [3, 1, 3], "inflate": 0.01, "uv": [29, 0]}
]
},
{
"name": "locator_foot_secondary",
"parent": "left_foot",
"pivot": [2.5, 0.5, -1.25],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [2.5, 0.5, -1.25]
}
},
{
"name": "right_leg",
"parent": "legs",
"pivot": [-2.5, 2, 0.25],
"cubes": [
{"origin": [-3, 0.5, -0.75], "size": [1, 2, 2], "uv": [0, 3]}
]
},
{
"name": "right_foot",
"parent": "right_leg",
"pivot": [-2.5, 1, 0.25],
"cubes": [
{"origin": [-4, 0, -1.75], "size": [3, 1, 4], "uv": [0, 25]}
]
},
{
"name": "right_toe",
"parent": "right_foot",
"pivot": [-2.5, 0, -1.75],
"cubes": [
{"origin": [-4, 0, -4.75], "size": [3, 1, 3], "inflate": 0.01, "uv": [25, 27]}
]
},
{
"name": "locator_foot_primary",
"parent": "right_foot",
"pivot": [-2.5, 0.5, -1.25],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-2.5, 0.5, -1.25]
}
}
]
@@ -1,441 +0,0 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.sudowoodo",
"texture_width": 128,
"texture_height": 64,
"visible_bounds_width": 4,
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
},
"bones": [
{
"name": "sudowoodo",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "sudowoodo",
"pivot": [0, 22, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 7.5, 0],
"cubes": [
{"origin": [-3.5, 6, -3.5], "size": [7, 11, 7], "uv": [0, 18]}
]
},
{
"name": "torso2",
"parent": "torso",
"pivot": [0, 16.5, 0],
"cubes": [
{"origin": [-3.5, 16, -3.5], "size": [7, 11, 7], "inflate": 0.01, "uv": [0, 0]}
]
},
{
"name": "head",
"parent": "torso2",
"pivot": [0, 26, 0],
"cubes": [
{"origin": [-3.5, 25.5, -3.5], "size": [7, 9, 7], "inflate": 0.02, "uv": [28, 0]},
{"origin": [-1, 33.5, -1], "size": [2, 5, 2], "inflate": 0.01, "uv": [21, 0]}
]
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 30.5, -3.5],
"locators": {
"item_face": [0, 30.5, -3.5]
}
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 30.25, -3.5],
"locators": {
"face": [0, 30.25, -3.5]
}
},
{
"name": "locator_item_hat",
"parent": "head",
"pivot": [0, 34.5, 0],
"locators": {
"item_hat": [0, 34.5, 0]
}
},
{
"name": "locator_head",
"parent": "head",
"pivot": [0, 34.5, -1],
"locators": {
"head": [0, 34.5, -1]
}
},
{
"name": "locator_mouth",
"parent": "head",
"pivot": [0, 28, -3.5],
"locators": {
"mouth": [0, 28, -3.5]
}
},
{
"name": "eye_left",
"parent": "head",
"pivot": [0, 6.5, 0],
"cubes": [
{"origin": [1, 29.5, -3.51], "size": [1, 3, 1], "inflate": 0.02, "uv": [0, 36]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [1.5, 31, -3.5],
"locators": {
"eye2": [1.5, 31, -3.5]
}
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [0, 6.5, 0.1],
"cubes": [
{"origin": [0.75, 29.5, -3.41], "size": [2, 3, 1], "inflate": 0.03, "uv": [0, 18]}
]
},
{
"name": "eye_right",
"parent": "head",
"pivot": [0, 6.5, 0],
"cubes": [
{"origin": [-2, 29.5, -3.51], "size": [1, 3, 1], "inflate": 0.02, "uv": [28, 26]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-1.5, 31, -3.5],
"locators": {
"eye1": [-1.5, 31, -3.5]
}
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [0, 6.5, 0.1],
"cubes": [
{"origin": [-2.75, 29.5, -3.41], "size": [2, 3, 1], "inflate": 0.03, "uv": [0, 0]}
]
},
{
"name": "mouth_open",
"parent": "head",
"pivot": [0, 28.16119, -2.91],
"cubes": [
{"origin": [1, 27.5, -3.41], "size": [2, 1, 1], "inflate": 0.02, "pivot": [1, 27.5, -2.91], "rotation": [0, 0, -15], "uv": [29, 2]},
{"origin": [-3, 27.5, -3.41], "size": [2, 1, 1], "inflate": 0.02, "pivot": [-1, 27.5, -2.91], "rotation": [0, 0, 15], "uv": [27, 0]},
{"origin": [-1, 27.5, -3.41], "size": [2, 1, 1], "inflate": 0.03, "uv": [21, 22]}
]
},
{
"name": "mouth_closed",
"parent": "head",
"pivot": [0, 28.16119, -3.01],
"cubes": [
{"origin": [1, 27.5, -3.51], "size": [2, 1, 1], "inflate": 0.02, "pivot": [1, 27.5, -3.01], "rotation": [0, 0, -15], "uv": [0, 22]},
{"origin": [-3, 27.5, -3.51], "size": [2, 1, 1], "inflate": 0.02, "pivot": [-1, 27.5, -3.01], "rotation": [0, 0, 15], "uv": [21, 20]},
{"origin": [-1, 27.5, -3.51], "size": [2, 1, 1], "inflate": 0.03, "uv": [0, 4]}
]
},
{
"name": "stem",
"parent": "head",
"pivot": [0, 6.5, 0]
},
{
"name": "stem_left",
"parent": "stem",
"pivot": [0, 38.5, 0],
"rotation": [0, 0, 60],
"cubes": [
{"origin": [0, 37.5, -1], "size": [2, 6, 2], "uv": [113, 25]}
]
},
{
"name": "stem_right",
"parent": "stem",
"pivot": [0, 38.5, 0],
"rotation": [0, 0, -60],
"cubes": [
{"origin": [-2, 37.5, -1], "size": [2, 6, 2], "uv": [105, 25]}
]
},
{
"name": "arm_left",
"parent": "torso2",
"pivot": [3, 23, 0],
"cubes": [
{"origin": [2, 22, -1], "size": [8, 2, 2], "uv": [66, 0]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [9.5, 23, 0],
"cubes": [
{"origin": [9, 22, -1], "size": [6, 2, 2], "inflate": 0.01, "uv": [66, 4]}
]
},
{
"name": "locator_hand_secondary",
"parent": "arm_left2",
"pivot": [14, 23, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [14, 23, 0]
}
},
{
"name": "finger_left",
"parent": "arm_left2",
"pivot": [14.5, 23, 0],
"cubes": [
{"origin": [14, 22.5, -0.5], "size": [5, 1, 1], "uv": [116, 18]}
]
},
{
"name": "leaf_left",
"parent": "finger_left",
"pivot": [18, 23, 0],
"cubes": [
{"origin": [17.5, 20.5, -2.5], "size": [5, 5, 5], "uv": [20, 36]}
]
},
{
"name": "finger_left2",
"parent": "arm_left2",
"pivot": [12.5, 23, 0],
"rotation": [0, 0, -55],
"cubes": [
{"origin": [12, 22.5, -0.5], "size": [5, 1, 1], "uv": [55, 39]}
]
},
{
"name": "leaf_left2",
"parent": "finger_left2",
"pivot": [15.5, 23, 0],
"cubes": [
{"origin": [15, 20.5, -2.5], "size": [5, 5, 5], "uv": [40, 36]}
]
},
{
"name": "finger_left3",
"parent": "arm_left2",
"pivot": [12.5, 23, 0],
"rotation": [0, 0, 55],
"cubes": [
{"origin": [12, 22.5, -0.5], "size": [5, 1, 1], "uv": [55, 37]}
]
},
{
"name": "leaf_left3",
"parent": "finger_left3",
"pivot": [14.5, 21, 0],
"cubes": [
{"origin": [15, 20.5, -2.5], "size": [5, 5, 5], "uv": [43, 21]}
]
},
{
"name": "arm_right",
"parent": "torso2",
"pivot": [-3, 23, 0],
"cubes": [
{"origin": [-10, 22, -1], "size": [8, 2, 2], "uv": [43, 16]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-9.5, 23, 0],
"cubes": [
{"origin": [-15, 22, -1], "size": [6, 2, 2], "inflate": 0.01, "uv": [48, 31]}
]
},
{
"name": "locator_item",
"parent": "arm_right2",
"pivot": [-13, 23, -1],
"rotation": [90, 0, 0],
"locators": {
"item": [-13, 23, -1]
}
},
{
"name": "locator_hand_primary",
"parent": "arm_right2",
"pivot": [-14, 23, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-14, 23, 0],
"physical": [-14, 23, 0],
"special": [-14, 23, 0]
}
},
{
"name": "finger_right",
"parent": "arm_right2",
"pivot": [-14.5, 23, 0],
"cubes": [
{"origin": [-19, 22.5, -0.5], "size": [5, 1, 1], "uv": [55, 35]}
]
},
{
"name": "leaf_right",
"parent": "finger_right",
"pivot": [-18, 23, 0],
"cubes": [
{"origin": [-22.5, 20.5, -2.5], "size": [5, 5, 5], "uv": [0, 36]}
]
},
{
"name": "finger_right2",
"parent": "arm_right2",
"pivot": [-12.5, 23, 0],
"rotation": [0, 0, 55],
"cubes": [
{"origin": [-17, 22.5, -0.5], "size": [5, 1, 1], "uv": [66, 8]}
]
},
{
"name": "leaf_right2",
"parent": "finger_right2",
"pivot": [-15.5, 23, 0],
"cubes": [
{"origin": [-20, 20.5, -2.5], "size": [5, 5, 5], "uv": [28, 26]}
]
},
{
"name": "finger_right3",
"parent": "arm_right2",
"pivot": [-12.5, 23, 0],
"rotation": [0, 0, -55],
"cubes": [
{"origin": [-17, 22.5, -0.5], "size": [5, 1, 1], "uv": [21, 18]}
]
},
{
"name": "leaf_right3",
"parent": "finger_right3",
"pivot": [-14.5, 21, 0],
"cubes": [
{"origin": [-20, 20.5, -2.5], "size": [5, 5, 5], "uv": [28, 16]}
]
},
{
"name": "leg_left",
"parent": "torso",
"pivot": [3.5, 9, 0],
"cubes": [
{"origin": [2, 5, -2], "size": [3, 6, 4], "uv": [91, 18]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [3.5, 5, -1],
"cubes": [
{"origin": [2.5, 1, -1], "size": [2, 4, 2], "uv": [66, 10]}
]
},
{
"name": "foot_left",
"parent": "leg_left2",
"pivot": [3.5, 1.5, 0.5],
"cubes": [
{"origin": [2, 0, -3.5], "size": [3, 2, 5], "uv": [49, 0]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left",
"pivot": [3.5, 1, -1],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [3.5, 1, -1]
}
},
{
"name": "leg_right",
"parent": "body",
"pivot": [-3.5, 9, 0],
"cubes": [
{"origin": [-5, 5, -2], "size": [3, 6, 4], "uv": [77, 18]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-3.5, 5, -1],
"cubes": [
{"origin": [-4.5, 1, -1], "size": [2, 4, 2], "uv": [76, 8]}
]
},
{
"name": "foot_right",
"parent": "leg_right2",
"pivot": [-3.5, 1.5, 0.5],
"cubes": [
{"origin": [-5, 0, -3.5], "size": [3, 2, 5], "uv": [105, 18]}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right",
"pivot": [-3.5, 1, -1],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-3.5, 1, -1]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 20, 0],
"locators": {
"middle": [0, 20, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 20, -6],
"locators": {
"target": [0, 20, -6]
}
},
{
"name": "locator_root",
"parent": "sudowoodo",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "sudowoodo",
"pivot": [0, 40, 0],
"locators": {
"top": [0, 40, 0]
}
}
]
}
]
}
@@ -0,0 +1,619 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.sudowoodo_female",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 4,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "sudowoodo",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "sudowoodo",
"pivot": [0, 0.5, 0],
"locators": {
"root": [0, 0.5, 0]
}
},
{
"name": "locator_top",
"parent": "sudowoodo",
"pivot": [0, 37, 0],
"locators": {
"top": [0, 37, 0]
}
},
{
"name": "body",
"parent": "sudowoodo",
"pivot": [0, 17, 0]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 20, 0],
"locators": {
"middle": [0, 20, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 20.5, -6],
"locators": {
"target": [0, 20.5, -6]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 7, 0],
"cubes": [
{"origin": [-3.5, 5, -3.5], "size": [7, 8, 7], "uv": [0, 0]}
]
},
{
"name": "torso2",
"parent": "torso",
"pivot": [0, 13, 0],
"cubes": [
{"origin": [-3.5, 12, -3.5], "size": [7, 9, 7], "inflate": 0.02, "uv": [0, 15]}
]
},
{
"name": "head",
"parent": "torso2",
"pivot": [0, 22, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 22, 0]
},
{
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 22, 0],
"cubes": [
{"origin": [-3.5, 21, -3.5], "size": [7, 10, 7], "uv": [0, 31]}
]
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 26.75, -3.5],
"locators": {
"face": [0, 26.75, -3.5]
}
},
{
"name": "locator_head",
"parent": "head_angle",
"pivot": [0, 31, -1],
"locators": {
"head": [0, 31, -1]
}
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 27.8, -3.5],
"locators": {
"item_face": [0, 27.8, -3.5]
}
},
{
"name": "locator_item_hat",
"parent": "head_angle",
"pivot": [0, 31, 0],
"locators": {
"item_hat": [0, 31, 0]
}
},
{
"name": "face",
"parent": "head_angle",
"pivot": [0, 26.5, -3.5]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 27.5, 0]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [1.5, 27.5, -3.01],
"cubes": [
{"origin": [1, 26.5, -3.53], "size": [1, 2, 1], "uv": [27, 32]}
]
},
{
"name": "eye_emote_left",
"parent": "eye_left",
"pivot": [1.5, 28.5, -3.44],
"cubes": [
{"origin": [1, 28, -3.44], "size": [1, 1, 1], "uv": [32, 58]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [1.5, 27.5, -3.5],
"locators": {
"eye2": [1.5, 27.5, -3.5]
}
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [1.5, 27.5, -3.43],
"cubes": [
{"origin": [0.5, 26.5, -3.43], "size": [2, 2, 1], "uv": [0, 61]}
]
},
{
"name": "eye_left_happy",
"parent": "eyes",
"pivot": [2, 27.5, -3.13],
"cubes": [
{"origin": [0.5, 26.5, -3.53], "size": [3, 2, 1], "inflate": -0.1, "uv": [6, 61]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-1.5, 27.5, -3.53],
"cubes": [
{"origin": [-2, 26.5, -3.53], "size": [1, 2, 1], "uv": [22, 32]}
]
},
{
"name": "eye_emote_right",
"parent": "eye_right",
"pivot": [-1.5, 28.5, -3.44],
"cubes": [
{"origin": [-2, 28, -3.44], "size": [1, 1, 1], "uv": [28, 58], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-1.5, 27.5, -3.5],
"locators": {
"eye1": [-1.5, 27.5, -3.5]
}
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-1.5, 27.5, -3.43],
"cubes": [
{"origin": [-2.5, 26.5, -3.43], "size": [2, 2, 1], "uv": [0, 58]}
]
},
{
"name": "eye_right_happy",
"parent": "eyes",
"pivot": [-2, 27.5, -3.13],
"cubes": [
{"origin": [-3.5, 26.5, -3.53], "size": [3, 2, 1], "inflate": -0.1, "uv": [6, 58]}
]
},
{
"name": "mouths",
"parent": "face",
"pivot": [0, 25.5, -3.51]
},
{
"name": "mouth_closed",
"parent": "mouths",
"pivot": [0, 25, -3.53],
"cubes": [
{"origin": [-2, 24.5, -3.53], "size": [4, 1, 1], "uv": [38, 62]}
]
},
{
"name": "mouth_closed_emote",
"parent": "mouth_closed",
"pivot": [0, 25.5, -3.53],
"cubes": [
{"origin": [-3, 25, -3.53], "size": [1, 1, 1], "uv": [28, 56]},
{"origin": [2, 25, -3.53], "size": [1, 1, 1], "uv": [32, 56], "mirror": true}
]
},
{
"name": "mouth_open",
"parent": "mouths",
"pivot": [0, 25, -3.43],
"cubes": [
{"origin": [-3, 24, -3.43], "size": [6, 2, 1], "uv": [14, 61]}
]
},
{
"name": "mouth_open_upset",
"parent": "mouths",
"pivot": [0, 25, -3.43],
"cubes": [
{"origin": [-3, 24, -3.43], "size": [6, 2, 1], "uv": [14, 58]}
]
},
{
"name": "mouth_open_small",
"parent": "mouths",
"pivot": [0, 25.05, -3.43],
"cubes": [
{"origin": [-0.5, 24.05, -3.43], "size": [1, 2, 1], "uv": [34, 61]}
]
},
{
"name": "mouth_open_tall",
"parent": "mouths",
"pivot": [0, 24.5, -3.43],
"cubes": [
{"origin": [-1, 23, -3.43], "size": [2, 3, 1], "uv": [28, 60]}
]
},
{
"name": "locator_mouth",
"parent": "mouths",
"pivot": [0, 24.5, -3.5],
"locators": {
"mouth": [0, 24.5, -3.5]
}
},
{
"name": "locator_special",
"parent": "mouths",
"pivot": [0, 24.5, -3.5],
"locators": {
"special2": [0, 24.5, -3.5]
}
},
{
"name": "face_ditto",
"parent": "head_angle",
"pivot": [0, 26.75, -3.4]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 27.5, -3.42],
"cubes": [
{"origin": [-2.5, 27, -3.42], "size": [5, 1, 0], "uv": [49, 55]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 27.5, -3.32],
"cubes": [
{"origin": [-3, 27, -3.32], "size": [6, 1, 0], "uv": [48, 56]},
{"origin": [-2.5, 27.5, -3.33], "size": [5, 1, 0], "uv": [49, 57]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 25.75, -3.4],
"cubes": [
{"origin": [-2, 25, -3.41], "size": [4, 1, 0], "uv": [50, 59]},
{"origin": [-3, 25.5, -3.41], "size": [6, 1, 0], "uv": [48, 58]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 25.5, -3.31],
"cubes": [
{"origin": [-3, 24.5, -3.31], "size": [6, 2, 0], "uv": [48, 60]}
]
},
{
"name": "stem",
"parent": "head_angle",
"pivot": [0, 30.5, 0],
"cubes": [
{"origin": [-1, 30.5, -1], "size": [2, 4, 2], "inflate": 0.01, "uv": [21, 16]}
]
},
{
"name": "stem_left",
"parent": "stem",
"pivot": [0, 34.5, 0],
"rotation": [0, 0, 60],
"cubes": [
{"origin": [0, 34.5, -1], "size": [2, 4, 2], "uv": [39, 45]}
]
},
{
"name": "stem_right",
"parent": "stem",
"pivot": [0, 34.5, 0],
"rotation": [0, 0, -60],
"cubes": [
{"origin": [-2, 34.5, -1], "size": [2, 4, 2], "uv": [31, 45]}
]
},
{
"name": "arms",
"parent": "torso2",
"pivot": [0, 20.5, 0]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-2.5, 20.5, 0],
"cubes": [
{"origin": [-8.5, 19.5, -1], "size": [6, 2, 2], "inflate": 0.02, "uv": [34, 0]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-8.5, 19.5, 1],
"cubes": [
{"origin": [-13.5, 19.5, -1], "size": [5, 2, 2], "uv": [50, 0]}
]
},
{
"name": "hand_right",
"parent": "arm_right2",
"pivot": [-13.5, 20.5, 0],
"cubes": [
{"origin": [-14.5, 19.5, -0.5], "size": [1, 2, 1], "inflate": 0.02, "uv": [21, 0]}
]
},
{
"name": "finger_right",
"parent": "hand_right",
"pivot": [-14.5, 20.5, 0],
"cubes": [
{"origin": [-16.5, 20, -0.5], "size": [2, 1, 1], "uv": [0, 15]}
]
},
{
"name": "leaf_right",
"parent": "finger_right",
"pivot": [-16, 20.5, 0],
"cubes": [
{"origin": [-20, 18.5, -2], "size": [4, 4, 4], "inflate": 0.27, "uv": [32, 28]}
]
},
{
"name": "finger_right_top",
"parent": "hand_right",
"pivot": [-13.5, 21.5, 0],
"cubes": [
{"origin": [-14.5, 21.5, -0.5], "size": [1, 2, 1], "uv": [0, 0]}
]
},
{
"name": "leaf_right_top",
"parent": "finger_right_top",
"pivot": [-14, 22.75, 0],
"cubes": [
{"origin": [-16, 22.75, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [48, 20]}
]
},
{
"name": "finger_right_bottom",
"parent": "hand_right",
"pivot": [-13.5, 19.5, 0],
"cubes": [
{"origin": [-14.5, 17.5, -0.5], "size": [1, 2, 1], "uv": [0, 31]}
]
},
{
"name": "leaf_right_bottom",
"parent": "finger_right_bottom",
"pivot": [-14, 18.25, 0],
"cubes": [
{"origin": [-16, 14.25, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [48, 36]}
]
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-13, 19.25, -1],
"locators": {
"item": [-13, 19.25, -1]
}
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-14.5, 20.5, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-14.5, 20.5, 0]
}
},
{
"name": "locator_physical",
"parent": "hand_right",
"pivot": [-14.5, 20.5, 0],
"locators": {
"physical": [-14.5, 20.5, 0]
}
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [2.5, 20.5, 0],
"cubes": [
{"origin": [2.5, 19.5, -1], "size": [6, 2, 2], "inflate": 0.02, "uv": [34, 4]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [8.5, 19.5, 1],
"cubes": [
{"origin": [8.5, 19.5, -1], "size": [5, 2, 2], "uv": [50, 4]}
]
},
{
"name": "hand_left",
"parent": "arm_left2",
"pivot": [13.5, 20.5, 0],
"cubes": [
{"origin": [13.5, 19.5, -0.5], "size": [1, 2, 1], "inflate": 0.02, "uv": [21, 3]}
]
},
{
"name": "finger_left",
"parent": "hand_left",
"pivot": [14.5, 20.5, 0],
"cubes": [
{"origin": [14.5, 20, -0.5], "size": [2, 1, 1], "uv": [0, 17]}
]
},
{
"name": "leaf_left",
"parent": "finger_left",
"pivot": [16, 20.5, 0],
"cubes": [
{"origin": [16, 18.5, -2], "size": [4, 4, 4], "inflate": 0.27, "uv": [48, 28]}
]
},
{
"name": "finger_left_top",
"parent": "hand_left",
"pivot": [13.5, 21.5, 0],
"cubes": [
{"origin": [13.5, 21.5, -0.5], "size": [1, 2, 1], "uv": [0, 3]}
]
},
{
"name": "leaf_left_top",
"parent": "finger_left_top",
"pivot": [14, 22.75, 0],
"cubes": [
{"origin": [12, 22.75, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [32, 20]}
]
},
{
"name": "finger_left_bottom",
"parent": "hand_left",
"pivot": [13.5, 19.5, 0],
"cubes": [
{"origin": [13.5, 17.5, -0.5], "size": [1, 2, 1], "uv": [0, 34]}
]
},
{
"name": "leaf_left_bottom",
"parent": "finger_left_bottom",
"pivot": [14, 18.25, 0],
"cubes": [
{"origin": [12, 14.25, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [32, 36]}
]
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [14.5, 20.5, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [14.5, 20.5, 0]
}
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 7.5, 0]
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-3.5, 7.5, 0],
"cubes": [
{"origin": [-5, 4, -2], "size": [3, 6, 4], "uv": [0, 48]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-3.5, 4, -1],
"cubes": [
{"origin": [-4.5, 1, -1], "size": [2, 3, 2], "uv": [28, 8]}
]
},
{
"name": "foot_right",
"parent": "leg_right2",
"pivot": [-3.5, 2, 0],
"cubes": [
{"origin": [-5, 0, -2.5], "size": [3, 2, 4], "inflate": 0.01, "uv": [36, 8]}
]
},
{
"name": "toes_right",
"parent": "foot_right",
"pivot": [-3.5, 0, -2.5],
"cubes": [
{"origin": [-5, 0, -5.5], "size": [3, 2, 3], "uv": [40, 14]}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right",
"pivot": [-3.5, 1, -1],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-3.5, 1, -1]
}
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [3.5, 7.5, 0],
"cubes": [
{"origin": [2, 4, -2], "size": [3, 6, 4], "uv": [14, 48]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [3.5, 4, -1],
"cubes": [
{"origin": [2.5, 1, -1], "size": [2, 3, 2], "uv": [28, 13]}
]
},
{
"name": "foot_left",
"parent": "leg_left2",
"pivot": [3.5, 2, 0],
"cubes": [
{"origin": [2, 0, -2.5], "size": [3, 2, 4], "inflate": 0.01, "uv": [50, 8]}
]
},
{
"name": "toes_left",
"parent": "foot_left",
"pivot": [3.5, 0, -2.5],
"cubes": [
{"origin": [2, 0, -5.5], "size": [3, 2, 3], "uv": [52, 14]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left",
"pivot": [3.5, 1, -1],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [3.5, 1, -1]
}
}
]
}
]
}
@@ -0,0 +1,619 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.sudowoodo_male",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 4,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "sudowoodo",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "sudowoodo",
"pivot": [0, 0.5, 0],
"locators": {
"root": [0, 0.5, 0]
}
},
{
"name": "locator_top",
"parent": "sudowoodo",
"pivot": [0, 37, 0],
"locators": {
"top": [0, 37, 0]
}
},
{
"name": "body",
"parent": "sudowoodo",
"pivot": [0, 17, 0]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 20, 0],
"locators": {
"middle": [0, 20, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 20.5, -6],
"locators": {
"target": [0, 20.5, -6]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 7, 0],
"cubes": [
{"origin": [-3.5, 5, -3.5], "size": [7, 8, 7], "uv": [0, 0]}
]
},
{
"name": "torso2",
"parent": "torso",
"pivot": [0, 13, 0],
"cubes": [
{"origin": [-3.5, 12, -3.5], "size": [7, 9, 7], "inflate": 0.02, "uv": [0, 15]}
]
},
{
"name": "head",
"parent": "torso2",
"pivot": [0, 22, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 22, 0]
},
{
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 22, 0],
"cubes": [
{"origin": [-3.5, 21, -3.5], "size": [7, 10, 7], "uv": [0, 31]}
]
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 26.75, -3.5],
"locators": {
"face": [0, 26.75, -3.5]
}
},
{
"name": "locator_head",
"parent": "head_angle",
"pivot": [0, 31, -1],
"locators": {
"head": [0, 31, -1]
}
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 27.8, -3.5],
"locators": {
"item_face": [0, 27.8, -3.5]
}
},
{
"name": "locator_item_hat",
"parent": "head_angle",
"pivot": [0, 31, 0],
"locators": {
"item_hat": [0, 31, 0]
}
},
{
"name": "face",
"parent": "head_angle",
"pivot": [0, 26.5, -3.5]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 27.5, 0]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [1.5, 27.5, -3.01],
"cubes": [
{"origin": [1, 26.5, -3.53], "size": [1, 2, 1], "uv": [27, 32]}
]
},
{
"name": "eye_emote_left",
"parent": "eye_left",
"pivot": [1.5, 28.5, -3.44],
"cubes": [
{"origin": [1, 28, -3.44], "size": [1, 1, 1], "uv": [32, 58]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [1.5, 27.5, -3.5],
"locators": {
"eye2": [1.5, 27.5, -3.5]
}
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [1.5, 27.5, -3.43],
"cubes": [
{"origin": [0.5, 26.5, -3.43], "size": [2, 2, 1], "uv": [0, 61]}
]
},
{
"name": "eye_left_happy",
"parent": "eyes",
"pivot": [2, 27.5, -3.13],
"cubes": [
{"origin": [0.5, 26.5, -3.53], "size": [3, 2, 1], "inflate": -0.1, "uv": [6, 61]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-1.5, 27.5, -3.53],
"cubes": [
{"origin": [-2, 26.5, -3.53], "size": [1, 2, 1], "uv": [22, 32]}
]
},
{
"name": "eye_emote_right",
"parent": "eye_right",
"pivot": [-1.5, 28.5, -3.44],
"cubes": [
{"origin": [-2, 28, -3.44], "size": [1, 1, 1], "uv": [28, 58], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-1.5, 27.5, -3.5],
"locators": {
"eye1": [-1.5, 27.5, -3.5]
}
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-1.5, 27.5, -3.43],
"cubes": [
{"origin": [-2.5, 26.5, -3.43], "size": [2, 2, 1], "uv": [0, 58]}
]
},
{
"name": "eye_right_happy",
"parent": "eyes",
"pivot": [-2, 27.5, -3.13],
"cubes": [
{"origin": [-3.5, 26.5, -3.53], "size": [3, 2, 1], "inflate": -0.1, "uv": [6, 58]}
]
},
{
"name": "mouths",
"parent": "face",
"pivot": [0, 25.5, -3.51]
},
{
"name": "mouth_closed",
"parent": "mouths",
"pivot": [0, 25, -3.53],
"cubes": [
{"origin": [-2, 24.5, -3.53], "size": [4, 1, 1], "uv": [38, 62]}
]
},
{
"name": "mouth_closed_emote",
"parent": "mouth_closed",
"pivot": [0, 25.5, -3.53],
"cubes": [
{"origin": [-3, 25, -3.53], "size": [1, 1, 1], "uv": [28, 56]},
{"origin": [2, 25, -3.53], "size": [1, 1, 1], "uv": [32, 56], "mirror": true}
]
},
{
"name": "mouth_open",
"parent": "mouths",
"pivot": [0, 25, -3.43],
"cubes": [
{"origin": [-3, 24, -3.43], "size": [6, 2, 1], "uv": [14, 61]}
]
},
{
"name": "mouth_open_upset",
"parent": "mouths",
"pivot": [0, 25, -3.43],
"cubes": [
{"origin": [-3, 24, -3.43], "size": [6, 2, 1], "uv": [14, 58]}
]
},
{
"name": "mouth_open_small",
"parent": "mouths",
"pivot": [0, 25.05, -3.43],
"cubes": [
{"origin": [-0.5, 24.05, -3.43], "size": [1, 2, 1], "uv": [34, 61]}
]
},
{
"name": "mouth_open_tall",
"parent": "mouths",
"pivot": [0, 24.5, -3.43],
"cubes": [
{"origin": [-1, 23, -3.43], "size": [2, 3, 1], "uv": [28, 60]}
]
},
{
"name": "locator_mouth",
"parent": "mouths",
"pivot": [0, 24.5, -3.5],
"locators": {
"mouth": [0, 24.5, -3.5]
}
},
{
"name": "locator_special",
"parent": "mouths",
"pivot": [0, 24.5, -3.5],
"locators": {
"special2": [0, 24.5, -3.5]
}
},
{
"name": "face_ditto",
"parent": "head_angle",
"pivot": [0, 26.75, -3.4]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 27.5, -3.42],
"cubes": [
{"origin": [-2.5, 27, -3.42], "size": [5, 1, 0], "uv": [49, 55]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 27.5, -3.32],
"cubes": [
{"origin": [-3, 27, -3.32], "size": [6, 1, 0], "uv": [48, 56]},
{"origin": [-2.5, 27.5, -3.33], "size": [5, 1, 0], "uv": [49, 57]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 25.75, -3.4],
"cubes": [
{"origin": [-2, 25, -3.41], "size": [4, 1, 0], "uv": [50, 59]},
{"origin": [-3, 25.5, -3.41], "size": [6, 1, 0], "uv": [48, 58]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 25.5, -3.31],
"cubes": [
{"origin": [-3, 24.5, -3.31], "size": [6, 2, 0], "uv": [48, 60]}
]
},
{
"name": "stem",
"parent": "head_angle",
"pivot": [0, 30.5, 0],
"cubes": [
{"origin": [-1, 30.5, -1], "size": [2, 4, 2], "inflate": 0.01, "uv": [21, 16]}
]
},
{
"name": "stem_left",
"parent": "stem",
"pivot": [0, 34.5, 0],
"rotation": [0, 0, 60],
"cubes": [
{"origin": [0, 34.5, -1], "size": [2, 5, 2], "uv": [56, 45]}
]
},
{
"name": "stem_right",
"parent": "stem",
"pivot": [0, 34.5, 0],
"rotation": [0, 0, -60],
"cubes": [
{"origin": [-2, 34.5, -1], "size": [2, 5, 2], "uv": [48, 45]}
]
},
{
"name": "arms",
"parent": "torso2",
"pivot": [0, 20.5, 0]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-2.5, 20.5, 0],
"cubes": [
{"origin": [-8.5, 19.5, -1], "size": [6, 2, 2], "inflate": 0.02, "uv": [34, 0]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-8.5, 19.5, 1],
"cubes": [
{"origin": [-13.5, 19.5, -1], "size": [5, 2, 2], "uv": [50, 0]}
]
},
{
"name": "hand_right",
"parent": "arm_right2",
"pivot": [-13.5, 20.5, 0],
"cubes": [
{"origin": [-14.5, 19.5, -0.5], "size": [1, 2, 1], "inflate": 0.02, "uv": [21, 0]}
]
},
{
"name": "finger_right",
"parent": "hand_right",
"pivot": [-14.5, 20.5, 0],
"cubes": [
{"origin": [-16.5, 20, -0.5], "size": [2, 1, 1], "uv": [0, 15]}
]
},
{
"name": "leaf_right",
"parent": "finger_right",
"pivot": [-16, 20.5, 0],
"cubes": [
{"origin": [-20, 18.5, -2], "size": [4, 4, 4], "inflate": 0.27, "uv": [32, 28]}
]
},
{
"name": "finger_right_top",
"parent": "hand_right",
"pivot": [-13.5, 21.5, 0],
"cubes": [
{"origin": [-14.5, 21.5, -0.5], "size": [1, 2, 1], "uv": [0, 0]}
]
},
{
"name": "leaf_right_top",
"parent": "finger_right_top",
"pivot": [-14, 22.75, 0],
"cubes": [
{"origin": [-16, 22.75, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [48, 20]}
]
},
{
"name": "finger_right_bottom",
"parent": "hand_right",
"pivot": [-13.5, 19.5, 0],
"cubes": [
{"origin": [-14.5, 17.5, -0.5], "size": [1, 2, 1], "uv": [0, 31]}
]
},
{
"name": "leaf_right_bottom",
"parent": "finger_right_bottom",
"pivot": [-14, 18.25, 0],
"cubes": [
{"origin": [-16, 14.25, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [48, 36]}
]
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-13, 19.25, -1],
"locators": {
"item": [-13, 19.25, -1]
}
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-14.5, 20.5, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-14.5, 20.5, 0]
}
},
{
"name": "locator_physical",
"parent": "hand_right",
"pivot": [-14.5, 20.5, 0],
"locators": {
"physical": [-14.5, 20.5, 0]
}
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [2.5, 20.5, 0],
"cubes": [
{"origin": [2.5, 19.5, -1], "size": [6, 2, 2], "inflate": 0.02, "uv": [34, 4]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [8.5, 19.5, 1],
"cubes": [
{"origin": [8.5, 19.5, -1], "size": [5, 2, 2], "uv": [50, 4]}
]
},
{
"name": "hand_left",
"parent": "arm_left2",
"pivot": [13.5, 20.5, 0],
"cubes": [
{"origin": [13.5, 19.5, -0.5], "size": [1, 2, 1], "inflate": 0.02, "uv": [21, 3]}
]
},
{
"name": "finger_left",
"parent": "hand_left",
"pivot": [14.5, 20.5, 0],
"cubes": [
{"origin": [14.5, 20, -0.5], "size": [2, 1, 1], "uv": [0, 17]}
]
},
{
"name": "leaf_left",
"parent": "finger_left",
"pivot": [16, 20.5, 0],
"cubes": [
{"origin": [16, 18.5, -2], "size": [4, 4, 4], "inflate": 0.27, "uv": [48, 28]}
]
},
{
"name": "finger_left_top",
"parent": "hand_left",
"pivot": [13.5, 21.5, 0],
"cubes": [
{"origin": [13.5, 21.5, -0.5], "size": [1, 2, 1], "uv": [0, 3]}
]
},
{
"name": "leaf_left_top",
"parent": "finger_left_top",
"pivot": [14, 22.75, 0],
"cubes": [
{"origin": [12, 22.75, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [32, 20]}
]
},
{
"name": "finger_left_bottom",
"parent": "hand_left",
"pivot": [13.5, 19.5, 0],
"cubes": [
{"origin": [13.5, 17.5, -0.5], "size": [1, 2, 1], "uv": [0, 34]}
]
},
{
"name": "leaf_left_bottom",
"parent": "finger_left_bottom",
"pivot": [14, 18.25, 0],
"cubes": [
{"origin": [12, 14.25, -2], "size": [4, 4, 4], "inflate": 0.25, "uv": [32, 36]}
]
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [14.5, 20.5, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [14.5, 20.5, 0]
}
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 7.5, 0]
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-3.5, 7.5, 0],
"cubes": [
{"origin": [-5, 4, -2], "size": [3, 6, 4], "uv": [0, 48]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-3.5, 4, -1],
"cubes": [
{"origin": [-4.5, 1, -1], "size": [2, 3, 2], "uv": [28, 8]}
]
},
{
"name": "foot_right",
"parent": "leg_right2",
"pivot": [-3.5, 2, 0],
"cubes": [
{"origin": [-5, 0, -2.5], "size": [3, 2, 4], "inflate": 0.01, "uv": [36, 8]}
]
},
{
"name": "toes_right",
"parent": "foot_right",
"pivot": [-3.5, 0, -2.5],
"cubes": [
{"origin": [-5, 0, -5.5], "size": [3, 2, 3], "uv": [40, 14]}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right",
"pivot": [-3.5, 1, -1],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-3.5, 1, -1]
}
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [3.5, 7.5, 0],
"cubes": [
{"origin": [2, 4, -2], "size": [3, 6, 4], "uv": [14, 48]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [3.5, 4, -1],
"cubes": [
{"origin": [2.5, 1, -1], "size": [2, 3, 2], "uv": [28, 13]}
]
},
{
"name": "foot_left",
"parent": "leg_left2",
"pivot": [3.5, 2, 0],
"cubes": [
{"origin": [2, 0, -2.5], "size": [3, 2, 4], "inflate": 0.01, "uv": [50, 8]}
]
},
{
"name": "toes_left",
"parent": "foot_left",
"pivot": [3.5, 0, -2.5],
"cubes": [
{"origin": [2, 0, -5.5], "size": [3, 2, 3], "uv": [52, 14]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left",
"pivot": [3.5, 1, -1],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [3.5, 1, -1]
}
}
]
}
]
}
@@ -1,132 +0,0 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.politoed",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "politoed",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "politoed",
"pivot": [0, 8, 0.75],
"cubes": [
{"origin": [-4, 3, -2.75], "size": [8, 9, 7], "uv": [0, 0]}
]
},
{
"name": "head",
"parent": "body",
"pivot": [0, 13.75, 0.5],
"cubes": [
{"origin": [-3.5, 11.5, -4], "size": [7, 5, 8], "uv": [0, 16]},
{"origin": [0, 16.25, -3], "size": [0, 5, 6], "pivot": [0, 18.75, 0], "rotation": [5, 0, 0], "uv": [14, 23]}
]
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 14.75, -2],
"rotation": [-2.5, 0, 0],
"cubes": [
{"origin": [3.5, 13.25, -3.5], "size": [0, 3, 3], "inflate": 0.02, "uv": [0, 16]},
{"origin": [-3.5, 13.25, -3.5], "size": [0, 3, 3], "inflate": 0.02, "uv": [0, 16], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eyes",
"pivot": [-3.5, 14.25, -2.5],
"rotation": [0, 90, 0],
"locators": {
"eye1": [-3.5, 14.25, -2.5]
}
},
{
"name": "locator_eye_left",
"parent": "eyes",
"pivot": [3.5, 14.25, -2.5],
"rotation": [0, -90, 0],
"locators": {
"eye2": [3.5, 14.25, -2.5]
}
},
{
"name": "leftleg",
"parent": "body",
"pivot": [3.25, 6, -0.25],
"cubes": [
{"origin": [1.75, 1, -1.25], "size": [3, 1, 3], "uv": [28, 34]},
{"origin": [1.75, 2, -2.25], "size": [3, 5, 4], "uv": [26, 25]}
]
},
{
"name": "leftfoot",
"parent": "leftleg",
"pivot": [3.25, 1, 0.5],
"cubes": [
{"origin": [1.75, 0, -3.75], "size": [3, 1, 6], "uv": [22, 16]}
]
},
{
"name": "rightleg",
"parent": "body",
"pivot": [-3.25, 6, -0.25],
"cubes": [
{"origin": [-4.75, 1, -1.25], "size": [3, 1, 3], "uv": [35, 0]},
{"origin": [-4.75, 2, -2.25], "size": [3, 5, 4], "uv": [0, 29]}
]
},
{
"name": "rightfoot",
"parent": "rightleg",
"pivot": [-3.25, 1, 0.5],
"cubes": [
{"origin": [-4.75, 0, -3.75], "size": [3, 1, 6], "uv": [23, 0]}
]
},
{
"name": "leftarm",
"parent": "body",
"pivot": [4, 11.5, -0.25],
"cubes": [
{"origin": [2, 8.5, -1.25], "size": [5, 3, 2], "uv": [34, 12]}
]
},
{
"name": "leftforearm",
"parent": "leftarm",
"pivot": [7, 11.5, 0.75],
"cubes": [
{"origin": [7, 8.5, -1.25], "size": [5, 3, 2], "uv": [30, 7]}
]
},
{
"name": "rightarm",
"parent": "body",
"pivot": [-4, 11.5, -0.25],
"cubes": [
{"origin": [-7, 8.5, -1.25], "size": [5, 3, 2], "uv": [34, 17]}
]
},
{
"name": "rightforearm",
"parent": "rightarm",
"pivot": [-7, 11.5, 0.75],
"cubes": [
{"origin": [-12, 8.5, -1.25], "size": [5, 3, 2], "uv": [14, 34]}
]
}
]
}
]
}
@@ -0,0 +1,608 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.politoed_female",
"texture_width": 128,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "politoed",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "politoed",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "politoed",
"pivot": [0, 26, 0],
"locators": {
"top": [0, 26, 0]
}
},
{
"name": "body",
"parent": "politoed",
"pivot": [0, 0, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 11, -6.5],
"locators": {
"target": [0, 11, -6.5]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 11, 0],
"locators": {
"middle": [0, 11, 0]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 7, 0],
"cubes": [
{"origin": [-5, 4.5, -4], "size": [10, 9, 9], "inflate": 0.01, "uv": [0, 0]}
]
},
{
"name": "head",
"parent": "torso",
"pivot": [0, 16, 0],
"cubes": [
{"origin": [-4.5, 15.5, -5], "size": [9, 5, 3], "uv": [0, 36]},
{"origin": [-4.5, 15, -5], "size": [1, 1, 3], "inflate": 0.01, "uv": [67, 36]},
{"origin": [3.5, 15, -5], "size": [1, 1, 3], "inflate": 0.01, "uv": [71, 26]},
{"origin": [-3.5, 15.5, -6.5], "size": [7, 4, 2], "inflate": 0.01, "uv": [0, 45]},
{"origin": [-4.5, 12.5, -2], "size": [9, 8, 6], "inflate": 0.01, "uv": [0, 19]}
]
},
{
"name": "jaw",
"parent": "head",
"pivot": [0, 15.5, -1],
"cubes": [
{"origin": [-4.5, 13, -5], "size": [9, 2, 3], "uv": [78, 20]},
{"origin": [-4.5, 14.51, -5], "size": [9, 1, 3], "inflate": -0.01, "uv": [77, 13]},
{"origin": [-3.5, 13, -6.5], "size": [7, 2, 2], "uv": [89, 27]},
{"origin": [-3.5, 14.5, -6.5], "size": [7, 1, 2], "inflate": -0.01, "uv": [78, 8]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw",
"pivot": [0, 15.5, -6.5],
"locators": {
"jaw2": [0, 15.5, -6.5]
}
},
{
"name": "tongue_short",
"parent": "jaw",
"pivot": [0, 16.5, -3],
"cubes": [
{"origin": [-2.5, 14.5, -5], "size": [5, 1, 3], "inflate": 0.01, "uv": [50, 36]}
]
},
{
"name": "tongue_long_base",
"parent": "jaw",
"pivot": [0, 15.4, -2],
"cubes": [
{"origin": [-1.5, 13.4, -5], "size": [3, 2, 3], "inflate": 0.02, "uv": [41, 59]}
]
},
{
"name": "tongue_long_mid",
"parent": "tongue_long_base",
"pivot": [0, 16, -4.75],
"cubes": [
{"origin": [-1, 14.5, -9.75], "size": [2, 1, 5], "inflate": 0.01, "uv": [50, 22]}
]
},
{
"name": "tongue_long_mid_bend",
"parent": "tongue_long_mid",
"pivot": [0, 16, -9.5],
"cubes": [
{"origin": [-1, 14.5, -14.5], "size": [2, 1, 5], "uv": [50, 29]}
]
},
{
"name": "tongue_long_end",
"parent": "tongue_long_mid_bend",
"pivot": [0, 16, -14.25],
"cubes": [
{"origin": [-1, 14.5, -18.25], "size": [2, 1, 4], "inflate": 0.01, "uv": [59, 41]}
]
},
{
"name": "tongue_long_tip",
"parent": "tongue_long_end",
"pivot": [0, 16, -18],
"cubes": [
{"origin": [-1.5, 14.5, -21], "size": [3, 1, 3], "inflate": 0.1, "uv": [59, 47]}
]
},
{
"name": "locator_physical",
"parent": "tongue_long_tip",
"pivot": [0, 15, -20.5],
"locators": {
"physical": [0, 15, -20.5]
}
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 18.5, -2.5]
},
{
"name": "left_eye",
"parent": "eyes",
"pivot": [4.5, 17.5, -3],
"cubes": [
{"origin": [3.5, 16.5, -5], "size": [1, 3, 3], "inflate": 0.01, "uv": [60, 0]}
]
},
{
"name": "left_pupil",
"parent": "left_eye",
"pivot": [4.5, 17.5, -3.5],
"cubes": [
{"origin": [3.5, 17, -5], "size": [1, 2, 2], "inflate": 0.02, "uv": [69, 52]}
]
},
{
"name": "locator_eye_left",
"parent": "left_pupil",
"pivot": [4.5, 18, -4.5],
"locators": {
"eye2": [4.5, 18, -4.5]
}
},
{
"name": "left_pupil_shocked",
"parent": "left_eye",
"pivot": [4.4, 17.5, -3.75],
"cubes": [
{"origin": [3.4, 17.5, -4.75], "size": [1, 1, 1], "inflate": 0.02, "uv": [3, 61]}
]
},
{
"name": "right_eye",
"parent": "eyes",
"pivot": [-4.5, 19, -3.5],
"cubes": [
{"origin": [-4.5, 16.5, -5], "size": [1, 3, 3], "inflate": 0.01, "uv": [60, 7]}
]
},
{
"name": "right_pupil",
"parent": "right_eye",
"pivot": [-4.5, 19, -4],
"cubes": [
{"origin": [-4.5, 17, -5], "size": [1, 2, 2], "inflate": 0.02, "uv": [80, 28]}
]
},
{
"name": "locator_eye_right",
"parent": "right_pupil",
"pivot": [-4.5, 18, -4.5],
"locators": {
"eye1": [-4.5, 18, -4.5]
}
},
{
"name": "right_pupil_shocked",
"parent": "right_eye",
"pivot": [-4.4, 18.5, -3.75],
"cubes": [
{"origin": [-4.4, 17.5, -4.75], "size": [1, 1, 1], "inflate": 0.02, "uv": [39, 19]}
]
},
{
"name": "eyelids",
"parent": "head",
"pivot": [0, 18.5, -2.5]
},
{
"name": "left_eyelid",
"parent": "eyelids",
"pivot": [3.9, 19, -3.4],
"cubes": [
{"origin": [3.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [65, 22]}
]
},
{
"name": "right_eyelid",
"parent": "eyelids",
"pivot": [-3.9, 19, -3.4],
"cubes": [
{"origin": [-4.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [65, 29]}
]
},
{
"name": "left_eyelid_angry",
"parent": "eyelids",
"pivot": [3.9, 20.25, -3.885],
"cubes": [
{"origin": [3.4, 18.5, -4.9], "size": [1, 1, 1], "inflate": 0.03, "uv": [8, 61]},
{"origin": [3.4, 19, -3.87], "size": [1, 1, 1], "inflate": 0.03, "uv": [72, 47]}
]
},
{
"name": "right_eyelid_angry",
"parent": "eyelids",
"pivot": [-3.9, 20.25, -3.885],
"cubes": [
{"origin": [-4.4, 18.5, -4.9], "size": [1, 1, 1], "inflate": 0.03, "uv": [44, 19]},
{"origin": [-4.4, 19, -3.87], "size": [1, 1, 1], "inflate": 0.03, "uv": [30, 62]}
]
},
{
"name": "left_eyelid_sad",
"parent": "eyelids",
"pivot": [3.9, 19.5, -3],
"cubes": [
{"origin": [3.4, 17.5, -4], "size": [1, 2, 2], "inflate": 0.03, "uv": [85, 52]}
]
},
{
"name": "right_eyelid_sad",
"parent": "eyelids",
"pivot": [-3.9, 19.5, -3],
"cubes": [
{"origin": [-4.4, 17.5, -4], "size": [1, 2, 2], "inflate": 0.03, "uv": [92, 52]}
]
},
{
"name": "left_eyelid_happy",
"parent": "eyelids",
"pivot": [3.9, 19, -3.4],
"cubes": [
{"origin": [3.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [77, 38]}
]
},
{
"name": "right_eyelid_happy",
"parent": "eyelids",
"pivot": [-3.9, 19, -3.4],
"cubes": [
{"origin": [-4.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [74, 31]}
]
},
{
"name": "left_eyelid_unamused",
"parent": "eyelids",
"pivot": [3.9, 20, -3.4],
"cubes": [
{"origin": [3.4, 18.5, -4.9], "size": [1, 1, 3], "inflate": 0.03, "uv": [69, 0]}
]
},
{
"name": "right_eyelid_unamused",
"parent": "eyelids",
"pivot": [-3.9, 20, -3.4],
"cubes": [
{"origin": [-4.4, 18.5, -4.9], "size": [1, 1, 3], "inflate": 0.03, "uv": [69, 5]}
]
},
{
"name": "left_eyelid_hurt",
"parent": "eyelids",
"pivot": [3.9, 19, -3.4],
"cubes": [
{"origin": [3.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [86, 38]},
{"origin": [3.42, 17, -3.9], "size": [1, 1, 1], "inflate": 0.02, "uv": [85, 57]}
]
},
{
"name": "right_eyelid_hurt",
"parent": "eyelids",
"pivot": [-3.9, 19, -3.4],
"cubes": [
{"origin": [-4.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [76, 52]},
{"origin": [-4.42, 17, -3.9], "size": [1, 1, 1], "inflate": 0.02, "uv": [23, 59]}
]
},
{
"name": "hair",
"parent": "head",
"pivot": [0, 21.5, 0],
"rotation": [15, 0, 0],
"cubes": [
{"origin": [0, 19.5, -8], "size": [0, 8, 9], "uv": [31, 19]}
]
},
{
"name": "cheeks",
"parent": "head",
"pivot": [0, 16, 1.5]
},
{
"name": "left_cheek",
"parent": "cheeks",
"pivot": [4, 15, -1],
"cubes": [
{"origin": [3.5, 14, -2], "size": [1, 2, 2], "inflate": 0.02, "uv": [69, 10]}
]
},
{
"name": "right_cheek",
"parent": "cheeks",
"pivot": [-4, 15, -1.25],
"cubes": [
{"origin": [-4.5, 14, -2], "size": [1, 2, 2], "inflate": 0.02, "uv": [69, 15]}
]
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 17.5, -6.5],
"locators": {
"face": [0, 17.5, -6.5]
}
},
{
"name": "locator_mouth",
"parent": "head",
"pivot": [0, 14.75, -4],
"locators": {
"mouth": [0, 14.75, -4],
"special": [0, 14.75, -4]
}
},
{
"name": "locator_head",
"parent": "head",
"pivot": [0, 20.5, -3],
"locators": {
"head": [0, 20.5, -3]
}
},
{
"name": "item_hat",
"parent": "head",
"pivot": [0, 20.5, -0.5],
"locators": {
"item_hat": [0, 20.5, -0.5]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 17.5, -6.5],
"locators": {
"item_face": [0, 17.5, -6.5]
}
},
{
"name": "locator_jaw_upper",
"parent": "head",
"pivot": [0, 15.5, -6.5],
"locators": {
"jaw1": [0, 15.5, -6.5]
}
},
{
"name": "arms",
"parent": "torso",
"pivot": [0, 13.25, -0.75]
},
{
"name": "left_arm",
"parent": "arms",
"pivot": [5, 12.75, -0.5],
"cubes": [
{"origin": [4.5, 11.25, -2], "size": [4, 2, 3], "inflate": 0.01, "uv": [13, 53]}
]
},
{
"name": "left_lower_arm",
"parent": "left_arm",
"pivot": [8.5, 12.25, 1],
"cubes": [
{"origin": [8.5, 11.25, -2], "size": [3, 2, 3], "uv": [56, 53]}
]
},
{
"name": "left_hand",
"parent": "left_lower_arm",
"pivot": [11.5, 12.25, -1.25],
"cubes": [
{"origin": [11.5, 11.25, -2], "size": [2, 2, 3], "inflate": 0.01, "uv": [54, 59]}
]
},
{
"name": "locator_hand_secondary",
"parent": "left_hand",
"pivot": [13, 12.25, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [13, 12.25, 0]
}
},
{
"name": "left_fingers",
"parent": "left_hand",
"pivot": [13.35, 13.25, -0.5],
"rotation": [0, -90, 0],
"cubes": [
{"origin": [12.85, 11.75, -1.65], "size": [1, 1, 1], "inflate": 0.1, "uv": [19, 48]},
{"origin": [11.5, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [50, 41]},
{"origin": [14.2, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [35, 62]}
]
},
{
"name": "right_arm",
"parent": "arms",
"pivot": [-5, 12.75, -0.5],
"cubes": [
{"origin": [-8.5, 11.25, -2], "size": [4, 2, 3], "inflate": 0.01, "uv": [41, 53]}
]
},
{
"name": "right_lower_arm",
"parent": "right_arm",
"pivot": [-8.5, 12.25, 1],
"cubes": [
{"origin": [-11.5, 11.25, -2], "size": [3, 2, 3], "uv": [13, 59]}
]
},
{
"name": "right_hand",
"parent": "right_lower_arm",
"pivot": [-11.5, 12.25, -1.25],
"cubes": [
{"origin": [-13.5, 11.25, -2], "size": [2, 2, 3], "inflate": 0.01, "uv": [76, 59]}
]
},
{
"name": "locator_hand_primary",
"parent": "right_hand",
"pivot": [-13, 12.25, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-13, 12.25, 0]
}
},
{
"name": "right_fingers",
"parent": "right_hand",
"pivot": [-13.35, 13.25, -0.5],
"rotation": [0, 90, 0],
"cubes": [
{"origin": [-13.85, 11.75, -1.65], "size": [1, 1, 1], "inflate": 0.1, "uv": [87, 60]},
{"origin": [-12.5, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [72, 41]},
{"origin": [-15.2, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [72, 44]}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 6.5, 0.5]
},
{
"name": "left_thigh",
"parent": "legs",
"pivot": [4, 6.5, 0.5],
"cubes": [
{"origin": [2, 3, -1.5], "size": [4, 5, 4], "inflate": -0.1, "uv": [25, 44]}
]
},
{
"name": "left_leg",
"parent": "left_thigh",
"pivot": [4, 3.5, 0.5],
"cubes": [
{"origin": [2.5, -0.25, -1], "size": [3, 5, 3], "inflate": -0.2, "uv": [0, 52]}
]
},
{
"name": "left_foot",
"parent": "left_leg",
"pivot": [4, -0.25, 1],
"cubes": [
{"origin": [2.5, -0.75, -4], "size": [3, 1, 6], "uv": [40, 0]},
{"origin": [3, -0.76, -1.5], "size": [2, 1, 3], "uv": [65, 59]}
]
},
{
"name": "locator_foot_secondary",
"parent": "left_foot",
"pivot": [4, -0.25, -1.75],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [4, -0.25, -1.75]
}
},
{
"name": "left_toes",
"parent": "left_foot",
"pivot": [4, -0.25, -3.75],
"cubes": [
{"origin": [3.5, -0.75, -4.85], "size": [1, 1, 1], "inflate": 0.1, "uv": [39, 16]},
{"origin": [2.15, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [44, 16]},
{"origin": [4.85, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [19, 45]}
]
},
{
"name": "left_leg_correction",
"parent": "left_leg",
"pivot": [4, 3.5, 0.5],
"cubes": [
{"origin": [2.5, -0.25, -1], "size": [3, 3, 3], "inflate": -0.21, "uv": [91, 0]}
]
},
{
"name": "right_thigh",
"parent": "legs",
"pivot": [-4, 6.5, 0.5],
"cubes": [
{"origin": [-6, 3, -1.5], "size": [4, 5, 4], "inflate": -0.1, "uv": [42, 44]}
]
},
{
"name": "right_leg",
"parent": "right_thigh",
"pivot": [-4, 3.5, 0.5],
"cubes": [
{"origin": [-5.5, -0.25, -1], "size": [3, 5, 3], "inflate": -0.2, "uv": [28, 53]}
]
},
{
"name": "right_foot",
"parent": "right_leg",
"pivot": [-4, -0.25, 1],
"cubes": [
{"origin": [-5.5, -0.75, -4], "size": [3, 1, 6], "uv": [40, 8]},
{"origin": [-5, -0.76, -1.5], "size": [2, 1, 3], "uv": [83, 33]}
]
},
{
"name": "locator_foot_primary",
"parent": "right_foot",
"pivot": [-4, -0.25, -1.75],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-4, -0.25, -1.75]
}
},
{
"name": "right_toes",
"parent": "right_foot",
"pivot": [-4, -0.25, -3.75],
"cubes": [
{"origin": [-4.5, -0.75, -4.85], "size": [1, 1, 1], "inflate": 0.1, "uv": [91, 58]},
{"origin": [-3.15, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [91, 62]},
{"origin": [-5.85, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [73, 59]}
]
},
{
"name": "right_leg_correction",
"parent": "right_leg",
"pivot": [-4, 3.5, 0.5],
"cubes": [
{"origin": [-5.5, -0.25, -1], "size": [3, 3, 3], "inflate": -0.21, "uv": [78, 0], "mirror": true}
]
}
]
}
]
}
@@ -0,0 +1,608 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.politoed_male",
"texture_width": 128,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "politoed",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "politoed",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "politoed",
"pivot": [0, 26, 0],
"locators": {
"top": [0, 26, 0]
}
},
{
"name": "body",
"parent": "politoed",
"pivot": [0, 0, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 11, -6.5],
"locators": {
"target": [0, 11, -6.5]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 11, 0],
"locators": {
"middle": [0, 11, 0]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 7, 0],
"cubes": [
{"origin": [-5, 4.5, -4], "size": [10, 9, 9], "inflate": 0.01, "uv": [0, 0]}
]
},
{
"name": "head",
"parent": "torso",
"pivot": [0, 16, 0],
"cubes": [
{"origin": [-4.5, 15.5, -5], "size": [9, 5, 3], "uv": [0, 36]},
{"origin": [-4.5, 15, -5], "size": [1, 1, 3], "inflate": 0.01, "uv": [67, 36]},
{"origin": [3.5, 15, -5], "size": [1, 1, 3], "inflate": 0.01, "uv": [71, 26]},
{"origin": [-3.5, 15.5, -6.5], "size": [7, 4, 2], "inflate": 0.01, "uv": [0, 45]},
{"origin": [-4.5, 12.5, -2], "size": [9, 8, 6], "inflate": 0.01, "uv": [0, 19]}
]
},
{
"name": "jaw",
"parent": "head",
"pivot": [0, 15.5, -1],
"cubes": [
{"origin": [-4.5, 13, -5], "size": [9, 2, 3], "uv": [78, 20]},
{"origin": [-4.5, 14.51, -5], "size": [9, 1, 3], "inflate": -0.01, "uv": [77, 13]},
{"origin": [-3.5, 13, -6.5], "size": [7, 2, 2], "uv": [89, 27]},
{"origin": [-3.5, 14.5, -6.5], "size": [7, 1, 2], "inflate": -0.01, "uv": [78, 8]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw",
"pivot": [0, 15.5, -6.5],
"locators": {
"jaw2": [0, 15.5, -6.5]
}
},
{
"name": "tongue_short",
"parent": "jaw",
"pivot": [0, 16.5, -3],
"cubes": [
{"origin": [-2.5, 14.5, -5], "size": [5, 1, 3], "inflate": 0.01, "uv": [50, 36]}
]
},
{
"name": "tongue_long_base",
"parent": "jaw",
"pivot": [0, 15.4, -2],
"cubes": [
{"origin": [-1.5, 13.4, -5], "size": [3, 2, 3], "inflate": 0.02, "uv": [41, 59]}
]
},
{
"name": "tongue_long_mid",
"parent": "tongue_long_base",
"pivot": [0, 16, -4.75],
"cubes": [
{"origin": [-1, 14.5, -9.75], "size": [2, 1, 5], "inflate": 0.01, "uv": [50, 22]}
]
},
{
"name": "tongue_long_mid_bend",
"parent": "tongue_long_mid",
"pivot": [0, 16, -9.5],
"cubes": [
{"origin": [-1, 14.5, -14.5], "size": [2, 1, 5], "uv": [50, 29]}
]
},
{
"name": "tongue_long_end",
"parent": "tongue_long_mid_bend",
"pivot": [0, 16, -14.25],
"cubes": [
{"origin": [-1, 14.5, -18.25], "size": [2, 1, 4], "inflate": 0.01, "uv": [59, 41]}
]
},
{
"name": "tongue_long_tip",
"parent": "tongue_long_end",
"pivot": [0, 16, -18],
"cubes": [
{"origin": [-1.5, 14.5, -21], "size": [3, 1, 3], "inflate": 0.1, "uv": [59, 47]}
]
},
{
"name": "locator_physical",
"parent": "tongue_long_tip",
"pivot": [0, 15, -20.5],
"locators": {
"physical": [0, 15, -20.5]
}
},
{
"name": "eyes",
"parent": "head",
"pivot": [0, 18.5, -2.5]
},
{
"name": "left_eye",
"parent": "eyes",
"pivot": [4.5, 17.5, -3],
"cubes": [
{"origin": [3.5, 16.5, -5], "size": [1, 3, 3], "inflate": 0.01, "uv": [60, 0]}
]
},
{
"name": "left_pupil",
"parent": "left_eye",
"pivot": [4.5, 17.5, -3.5],
"cubes": [
{"origin": [3.5, 17, -5], "size": [1, 2, 2], "inflate": 0.02, "uv": [69, 52]}
]
},
{
"name": "locator_eye_left",
"parent": "left_pupil",
"pivot": [4.5, 18, -4.5],
"locators": {
"eye2": [4.5, 18, -4.5]
}
},
{
"name": "left_pupil_shocked",
"parent": "left_eye",
"pivot": [4.4, 17.5, -3.75],
"cubes": [
{"origin": [3.4, 17.5, -4.75], "size": [1, 1, 1], "inflate": 0.02, "uv": [3, 61]}
]
},
{
"name": "right_eye",
"parent": "eyes",
"pivot": [-4.5, 19, -3.5],
"cubes": [
{"origin": [-4.5, 16.5, -5], "size": [1, 3, 3], "inflate": 0.01, "uv": [60, 7]}
]
},
{
"name": "right_pupil",
"parent": "right_eye",
"pivot": [-4.5, 19, -4],
"cubes": [
{"origin": [-4.5, 17, -5], "size": [1, 2, 2], "inflate": 0.02, "uv": [80, 28]}
]
},
{
"name": "locator_eye_right",
"parent": "right_pupil",
"pivot": [-4.5, 18, -4.5],
"locators": {
"eye1": [-4.5, 18, -4.5]
}
},
{
"name": "right_pupil_shocked",
"parent": "right_eye",
"pivot": [-4.4, 18.5, -3.75],
"cubes": [
{"origin": [-4.4, 17.5, -4.75], "size": [1, 1, 1], "inflate": 0.02, "uv": [39, 19]}
]
},
{
"name": "eyelids",
"parent": "head",
"pivot": [0, 18.5, -2.5]
},
{
"name": "left_eyelid",
"parent": "eyelids",
"pivot": [3.9, 19, -3.4],
"cubes": [
{"origin": [3.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [65, 22]}
]
},
{
"name": "right_eyelid",
"parent": "eyelids",
"pivot": [-3.9, 19, -3.4],
"cubes": [
{"origin": [-4.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [65, 29]}
]
},
{
"name": "left_eyelid_angry",
"parent": "eyelids",
"pivot": [3.9, 20.25, -3.885],
"cubes": [
{"origin": [3.4, 18.5, -4.9], "size": [1, 1, 1], "inflate": 0.03, "uv": [8, 61]},
{"origin": [3.4, 19, -3.87], "size": [1, 1, 1], "inflate": 0.03, "uv": [72, 47]}
]
},
{
"name": "right_eyelid_angry",
"parent": "eyelids",
"pivot": [-3.9, 20.25, -3.885],
"cubes": [
{"origin": [-4.4, 18.5, -4.9], "size": [1, 1, 1], "inflate": 0.03, "uv": [44, 19]},
{"origin": [-4.4, 19, -3.87], "size": [1, 1, 1], "inflate": 0.03, "uv": [30, 62]}
]
},
{
"name": "left_eyelid_sad",
"parent": "eyelids",
"pivot": [3.9, 19.5, -3],
"cubes": [
{"origin": [3.4, 17.5, -4], "size": [1, 2, 2], "inflate": 0.03, "uv": [85, 52]}
]
},
{
"name": "right_eyelid_sad",
"parent": "eyelids",
"pivot": [-3.9, 19.5, -3],
"cubes": [
{"origin": [-4.4, 17.5, -4], "size": [1, 2, 2], "inflate": 0.03, "uv": [92, 52]}
]
},
{
"name": "left_eyelid_happy",
"parent": "eyelids",
"pivot": [3.9, 19, -3.4],
"cubes": [
{"origin": [3.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [77, 38]}
]
},
{
"name": "right_eyelid_happy",
"parent": "eyelids",
"pivot": [-3.9, 19, -3.4],
"cubes": [
{"origin": [-4.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [74, 31]}
]
},
{
"name": "left_eyelid_unamused",
"parent": "eyelids",
"pivot": [3.9, 20, -3.4],
"cubes": [
{"origin": [3.4, 18.5, -4.9], "size": [1, 1, 3], "inflate": 0.03, "uv": [69, 0]}
]
},
{
"name": "right_eyelid_unamused",
"parent": "eyelids",
"pivot": [-3.9, 20, -3.4],
"cubes": [
{"origin": [-4.4, 18.5, -4.9], "size": [1, 1, 3], "inflate": 0.03, "uv": [69, 5]}
]
},
{
"name": "left_eyelid_hurt",
"parent": "eyelids",
"pivot": [3.9, 19, -3.4],
"cubes": [
{"origin": [3.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [86, 38]},
{"origin": [3.42, 17, -3.9], "size": [1, 1, 1], "inflate": 0.02, "uv": [85, 57]}
]
},
{
"name": "right_eyelid_hurt",
"parent": "eyelids",
"pivot": [-3.9, 19, -3.4],
"cubes": [
{"origin": [-4.4, 16.5, -4.9], "size": [1, 3, 3], "inflate": 0.03, "uv": [76, 52]},
{"origin": [-4.42, 17, -3.9], "size": [1, 1, 1], "inflate": 0.02, "uv": [23, 59]}
]
},
{
"name": "hair",
"parent": "head",
"pivot": [0, 21.5, 0],
"rotation": [15, 0, 0],
"cubes": [
{"origin": [0, 19.5, -8], "size": [0, 8, 9], "uv": [31, 19]}
]
},
{
"name": "cheeks",
"parent": "head",
"pivot": [0, 16, 1.5]
},
{
"name": "left_cheek",
"parent": "cheeks",
"pivot": [4, 15, -0.5],
"cubes": [
{"origin": [3.5, 13.5, -2], "size": [1, 3, 3], "inflate": 0.02, "uv": [77, 45]}
]
},
{
"name": "right_cheek",
"parent": "cheeks",
"pivot": [-4, 15, -0.5],
"cubes": [
{"origin": [-4.5, 13.5, -2], "size": [1, 3, 3], "inflate": 0.02, "uv": [87, 45]}
]
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 17.5, -6.5],
"locators": {
"face": [0, 17.5, -6.5]
}
},
{
"name": "locator_mouth",
"parent": "head",
"pivot": [0, 14.75, -4],
"locators": {
"mouth": [0, 14.75, -4],
"special": [0, 14.75, -4]
}
},
{
"name": "locator_head",
"parent": "head",
"pivot": [0, 20.5, -3],
"locators": {
"head": [0, 20.5, -3]
}
},
{
"name": "item_hat",
"parent": "head",
"pivot": [0, 20.5, -0.5],
"locators": {
"item_hat": [0, 20.5, -0.5]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 17.5, -6.5],
"locators": {
"item_face": [0, 17.5, -6.5]
}
},
{
"name": "locator_jaw_upper",
"parent": "head",
"pivot": [0, 15.5, -6.5],
"locators": {
"jaw1": [0, 15.5, -6.5]
}
},
{
"name": "arms",
"parent": "torso",
"pivot": [0, 13.25, -0.75]
},
{
"name": "left_arm",
"parent": "arms",
"pivot": [5, 12.75, -0.5],
"cubes": [
{"origin": [4.5, 11.25, -2], "size": [4, 2, 3], "inflate": 0.01, "uv": [13, 53]}
]
},
{
"name": "left_lower_arm",
"parent": "left_arm",
"pivot": [8.5, 12.25, 1],
"cubes": [
{"origin": [8.5, 11.25, -2], "size": [3, 2, 3], "uv": [56, 53]}
]
},
{
"name": "left_hand",
"parent": "left_lower_arm",
"pivot": [11.5, 12.25, -1.25],
"cubes": [
{"origin": [11.5, 11.25, -2], "size": [2, 2, 3], "inflate": 0.01, "uv": [54, 59]}
]
},
{
"name": "locator_hand_secondary",
"parent": "left_hand",
"pivot": [13, 12.25, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [13, 12.25, 0]
}
},
{
"name": "left_fingers",
"parent": "left_hand",
"pivot": [13.35, 13.25, -0.5],
"rotation": [0, -90, 0],
"cubes": [
{"origin": [12.85, 11.75, -1.65], "size": [1, 1, 1], "inflate": 0.1, "uv": [19, 48]},
{"origin": [11.5, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [50, 41]},
{"origin": [14.2, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [35, 62]}
]
},
{
"name": "right_arm",
"parent": "arms",
"pivot": [-5, 12.75, -0.5],
"cubes": [
{"origin": [-8.5, 11.25, -2], "size": [4, 2, 3], "inflate": 0.01, "uv": [41, 53]}
]
},
{
"name": "right_lower_arm",
"parent": "right_arm",
"pivot": [-8.5, 12.25, 1],
"cubes": [
{"origin": [-11.5, 11.25, -2], "size": [3, 2, 3], "uv": [13, 59]}
]
},
{
"name": "right_hand",
"parent": "right_lower_arm",
"pivot": [-11.5, 12.25, -1.25],
"cubes": [
{"origin": [-13.5, 11.25, -2], "size": [2, 2, 3], "inflate": 0.01, "uv": [76, 59]}
]
},
{
"name": "locator_hand_primary",
"parent": "right_hand",
"pivot": [-13, 12.25, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-13, 12.25, 0]
}
},
{
"name": "right_fingers",
"parent": "right_hand",
"pivot": [-13.35, 13.25, -0.5],
"rotation": [0, 90, 0],
"cubes": [
{"origin": [-13.85, 11.75, -1.65], "size": [1, 1, 1], "inflate": 0.1, "uv": [87, 60]},
{"origin": [-12.5, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [72, 41]},
{"origin": [-15.2, 11.75, -1.15], "size": [1, 1, 1], "inflate": 0.1, "uv": [72, 44]}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 6.5, 0.5]
},
{
"name": "left_thigh",
"parent": "legs",
"pivot": [4, 6.5, 0.5],
"cubes": [
{"origin": [2, 3, -1.5], "size": [4, 5, 4], "inflate": -0.1, "uv": [25, 44]}
]
},
{
"name": "left_leg",
"parent": "left_thigh",
"pivot": [4, 3.5, 0.5],
"cubes": [
{"origin": [2.5, -0.25, -1], "size": [3, 5, 3], "inflate": -0.2, "uv": [0, 52]}
]
},
{
"name": "left_foot",
"parent": "left_leg",
"pivot": [4, -0.25, 1],
"cubes": [
{"origin": [2.5, -0.75, -4], "size": [3, 1, 6], "uv": [40, 0]},
{"origin": [3, -0.76, -1.5], "size": [2, 1, 3], "uv": [65, 59]}
]
},
{
"name": "locator_foot_secondary",
"parent": "left_foot",
"pivot": [4, -0.25, -1.75],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [4, -0.25, -1.75]
}
},
{
"name": "left_toes",
"parent": "left_foot",
"pivot": [4, -0.25, -3.75],
"cubes": [
{"origin": [3.5, -0.75, -4.85], "size": [1, 1, 1], "inflate": 0.1, "uv": [39, 16]},
{"origin": [2.15, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [44, 16]},
{"origin": [4.85, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [19, 45]}
]
},
{
"name": "left_leg_correction",
"parent": "left_leg",
"pivot": [4, 3.5, 0.5],
"cubes": [
{"origin": [2.5, -0.25, -1], "size": [3, 3, 3], "inflate": -0.21, "uv": [91, 0]}
]
},
{
"name": "right_thigh",
"parent": "legs",
"pivot": [-4, 6.5, 0.5],
"cubes": [
{"origin": [-6, 3, -1.5], "size": [4, 5, 4], "inflate": -0.1, "uv": [42, 44]}
]
},
{
"name": "right_leg",
"parent": "right_thigh",
"pivot": [-4, 3.5, 0.5],
"cubes": [
{"origin": [-5.5, -0.25, -1], "size": [3, 5, 3], "inflate": -0.2, "uv": [28, 53]}
]
},
{
"name": "right_foot",
"parent": "right_leg",
"pivot": [-4, -0.25, 1],
"cubes": [
{"origin": [-5.5, -0.75, -4], "size": [3, 1, 6], "uv": [40, 8]},
{"origin": [-5, -0.76, -1.5], "size": [2, 1, 3], "uv": [83, 33]}
]
},
{
"name": "locator_foot_primary",
"parent": "right_foot",
"pivot": [-4, -0.25, -1.75],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-4, -0.25, -1.75]
}
},
{
"name": "right_toes",
"parent": "right_foot",
"pivot": [-4, -0.25, -3.75],
"cubes": [
{"origin": [-4.5, -0.75, -4.85], "size": [1, 1, 1], "inflate": 0.1, "uv": [91, 58]},
{"origin": [-3.15, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [91, 62]},
{"origin": [-5.85, -0.75, -4.6], "size": [1, 1, 1], "inflate": 0.1, "uv": [73, 59]}
]
},
{
"name": "right_leg_correction",
"parent": "right_leg",
"pivot": [-4, 3.5, 0.5],
"cubes": [
{"origin": [-5.5, -0.25, -1], "size": [3, 3, 3], "inflate": -0.21, "uv": [78, 0], "mirror": true}
]
}
]
}
]
}
@@ -5,8 +5,8 @@
"description": {
"identifier": "geometry.shroomish",
"texture_width": 64,
"texture_height": 32,
"visible_bounds_width": 2,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
@@ -25,147 +25,336 @@
"parent": "body",
"pivot": [0, 1.5, 0],
"cubes": [
{"origin": [-4.5, 1, -4.5], "size": [9, 8, 9], "uv": [0, 1]}
]
},
{
"name": "skirt_left",
"parent": "torso",
"pivot": [4.5, 3.5, 0],
"rotation": [0, 0, 45],
"cubes": [
{"origin": [4.5, 3.5, -4.5], "size": [3, 0, 9], "uv": [37, 1]}
]
},
{
"name": "skirt_right",
"parent": "torso",
"pivot": [-4.5, 3.5, 0],
"rotation": [0, 0, -45],
"cubes": [
{"origin": [-7.5, 3.5, -4.5], "size": [3, 0, 9], "uv": [15, 18]}
]
},
{
"name": "skirt_front",
"parent": "torso",
"pivot": [0, 3.5, -4.5],
"rotation": [45, 0, 0],
"cubes": [
{"origin": [-4.5, 3.5, -7.5], "size": [9, 0, 3], "uv": [15, 27]}
]
},
{
"name": "skirt_back",
"parent": "torso",
"pivot": [0, 3.5, 4.5],
"rotation": [-45, 0, 0],
"cubes": [
{"origin": [-4.5, 3.5, 4.5], "size": [9, 0, 3], "uv": [37, 10]}
{"origin": [-6, 1, -6], "size": [12, 10, 12], "uv": [0, 0]}
]
},
{
"name": "face",
"parent": "torso",
"pivot": [0, 6.21667, -4.525]
"pivot": [0, 6.21667, -6.025]
},
{
"name": "eye_left",
"name": "eyes",
"parent": "face",
"pivot": [1.5, 6.45, -4.01],
"cubes": [
{"origin": [1, 5.95, -4.51], "size": [1, 1, 1], "uv": [53, 2]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [1.5, 6.5, -4.5],
"locators": {
"eye2": [1.5, 6.5, -4.5]
}
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [1.5, 6.45, -3.91],
"cubes": [
{"origin": [0.5, 5.95, -4.41], "size": [2, 1, 1], "inflate": 0.01, "uv": [57, 2]}
]
"pivot": [1.5, 7.45, -5.51]
},
{
"name": "eye_right",
"parent": "face",
"pivot": [-1.5, 6.45, -4.01],
"parent": "eyes",
"pivot": [-1.5, 7.45, -5.51],
"cubes": [
{"origin": [-2, 5.95, -4.51], "size": [1, 1, 1], "uv": [53, 4], "mirror": true}
{"origin": [-2, 7, -6], "size": [1, 1, 1], "inflate": 0.01, "uv": [1, 39]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-1.5, 6.5, -4.5],
"pivot": [-1.5, 7.5, -6],
"locators": {
"eye1": [-1.5, 6.5, -4.5]
"eye1": [-1.5, 7.5, -6]
}
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-1.5, 6.45, -3.91],
"name": "eye_left",
"parent": "eyes",
"pivot": [1.5, 7.45, -5.51],
"cubes": [
{"origin": [-2.5, 5.95, -4.41], "size": [2, 1, 1], "inflate": 0.01, "uv": [57, 4], "mirror": true}
{"origin": [1, 7, -6], "size": [1, 1, 1], "inflate": 0.01, "uv": [1, 42], "mirror": true}
]
},
{
"name": "mouth_closed",
"parent": "face",
"pivot": [0, 4.70711, -4.51],
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [1.5, 7.5, -6],
"locators": {
"eye2": [1.5, 7.5, -6]
}
},
{
"name": "eyelids_right",
"parent": "eyes",
"pivot": [-1.5, 8, -5.4]
},
{
"name": "eyelid_annoyed_right",
"parent": "eyelids_right",
"pivot": [-1.5, 8, -5.4],
"cubes": [
{"origin": [-1.5, 3.5, -4.51], "size": [2, 2, 0], "pivot": [0, 4, -4.525], "rotation": [0, 0, 45], "uv": [1, 19]}
{"origin": [-2, 7.5, -5.9], "size": [1, 1, 1], "inflate": 0.02, "uv": [6, 39]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eyelids_right",
"pivot": [-2, 7.25, -5.4],
"cubes": [
{"origin": [-2.5, 6.5, -5.9], "size": [1, 1, 1], "inflate": 0.03, "uv": [11, 39]},
{"origin": [-3, 7, -5.9], "size": [2, 1, 1], "inflate": 0.02, "uv": [16, 39]}
]
},
{
"name": "eyelid_closed_right",
"parent": "eyelids_right",
"pivot": [-2, 7.5, -5.4],
"cubes": [
{"origin": [-3, 7, -5.9], "size": [2, 1, 1], "inflate": 0.02, "uv": [23, 39]}
]
},
{
"name": "eyelids_left",
"parent": "eyes",
"pivot": [1.5, 8, -5.4]
},
{
"name": "eyelid_annoyed_left",
"parent": "eyelids_left",
"pivot": [1.5, 8, -5.4],
"cubes": [
{"origin": [1, 7.5, -5.9], "size": [1, 1, 1], "inflate": 0.02, "uv": [6, 42], "mirror": true}
]
},
{
"name": "eyelid_happy_left",
"parent": "eyelids_left",
"pivot": [2, 7.25, -5.4],
"cubes": [
{"origin": [1.5, 6.5, -5.9], "size": [1, 1, 1], "inflate": 0.03, "uv": [11, 42], "mirror": true},
{"origin": [1, 7, -5.9], "size": [2, 1, 1], "inflate": 0.02, "uv": [16, 42], "mirror": true}
]
},
{
"name": "eyelid_closed_left",
"parent": "eyelids_left",
"pivot": [2, 7.5, -5.4],
"cubes": [
{"origin": [1, 7, -5.9], "size": [2, 1, 1], "inflate": 0.02, "uv": [23, 42], "mirror": true}
]
},
{
"name": "mouths",
"parent": "face",
"pivot": [0, 4.70711, -6.01]
},
{
"name": "mouth_closed",
"parent": "mouths",
"pivot": [0, 6, -5.52],
"cubes": [
{"origin": [-2.5, 5, -6], "size": [5, 2, 1], "inflate": 0.01, "uv": [23, 27]},
{"origin": [-1.5, 5.5, -6], "size": [3, 1, 1], "inflate": 0.01, "uv": [36, 28]}
]
},
{
"name": "mouth_open",
"parent": "face",
"pivot": [0, 4, -4.41],
"parent": "mouths",
"pivot": [0, 6, -5.4],
"cubes": [
{"origin": [-1.5, 2.5, -4.41], "size": [3, 3, 0], "pivot": [0, 4, -4.425], "rotation": [0, 0, 45], "uv": [10, 19]}
{"origin": [-2.5, 5, -5.9], "size": [5, 2, 1], "inflate": 0.01, "uv": [23, 31]},
{"origin": [-1.5, 5.5, -5.9], "size": [3, 1, 1], "inflate": 0.02, "uv": [36, 32]}
]
},
{
"name": "eyebrow",
"parent": "face",
"pivot": [0, 7.5, -4.01],
"name": "face_ditto",
"parent": "torso",
"pivot": [0, 6.75, -5.9]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 7.5, -5.92],
"cubes": [
{"origin": [-3.5, 7, -4.51], "size": [7, 1, 1], "uv": [1, 28]}
{"origin": [-3, 7, -5.92], "size": [6, 1, 0], "uv": [5, 46]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 7.5, -5.72],
"cubes": [
{"origin": [-2.5, 7, -5.82], "size": [7, 1, 0], "uv": [4, 48]},
{"origin": [-2, 7.5, -5.83], "size": [6, 1, 0], "uv": [5, 50]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 5.75, -5.9],
"cubes": [
{"origin": [-3.5, 5, -5.91], "size": [7, 1, 0], "uv": [4, 54]},
{"origin": [-4.5, 5.5, -5.91], "size": [9, 1, 0], "uv": [2, 52]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 5.5, -5.81],
"cubes": [
{"origin": [-3.5, 4.5, -5.81], "size": [7, 2, 0], "uv": [2, 56]}
]
},
{
"name": "eyebrows",
"parent": "torso",
"pivot": [0, 9, -5.51]
},
{
"name": "eyebrow_neutral",
"parent": "eyebrows",
"pivot": [0, 9, -5.51],
"cubes": [
{"origin": [-5, 8, -6], "size": [10, 2, 1], "inflate": 0.04, "uv": [0, 27]}
]
},
{
"name": "eyebrow_angry",
"parent": "eyebrows",
"pivot": [0, 9, -5.31],
"cubes": [
{"origin": [-5, 8, -5.9], "size": [10, 2, 1], "inflate": 0.04, "uv": [0, 31]}
]
},
{
"name": "eyebrow_sad",
"parent": "eyebrows",
"pivot": [0, 9, -5.31],
"cubes": [
{"origin": [-5, 8, -5.9], "size": [10, 2, 1], "inflate": 0.04, "uv": [0, 35]}
]
},
{
"name": "hair",
"parent": "torso",
"pivot": [0, 9, 0],
"pivot": [0, 11, 0]
},
{
"name": "hair_back_rotation",
"parent": "hair",
"pivot": [0, 11, 0]
},
{
"name": "hair_back",
"parent": "hair_back_rotation",
"pivot": [0, 11, 1.25],
"rotation": [-25, 0, 0],
"cubes": [
{"origin": [-1, 8, -1], "size": [2, 3, 0], "pivot": [0, 8.5, -1], "rotation": [17.5, 0, 0], "uv": [50, 20]},
{"origin": [-1, 8, -1], "size": [0, 3, 2], "pivot": [-1, 8.5, 0], "rotation": [0, 0, -17.5], "uv": [50, 15]},
{"origin": [-1, 8, 1], "size": [2, 3, 0], "pivot": [0, 8.5, 1], "rotation": [-17.5, 0, 0], "uv": [50, 23]},
{"origin": [1, 8, -1], "size": [0, 3, 2], "pivot": [1, 8.5, 0], "rotation": [0, 0, 17.5], "uv": [50, 24]}
{"origin": [-1, 10, 1.25], "size": [2, 3, 0], "uv": [52, 0]}
]
},
{
"name": "hair_back_left_rotation",
"parent": "hair",
"pivot": [0, 11, 0],
"rotation": [0, 72, 0]
},
{
"name": "hair_back_left",
"parent": "hair_back_left_rotation",
"pivot": [0, 11, 1.25],
"rotation": [-25, 0, 0],
"cubes": [
{"origin": [-1, 10, 1.25], "size": [2, 3, 0], "uv": [56, 0]}
]
},
{
"name": "hair_back_right_rotation",
"parent": "hair",
"pivot": [0, 11, 0],
"rotation": [0, -72, 0]
},
{
"name": "hair_back_right",
"parent": "hair_back_right_rotation",
"pivot": [0, 11, 1.25],
"rotation": [-25, 0, 0],
"cubes": [
{"origin": [-1, 10, 1.25], "size": [2, 3, 0], "uv": [52, 3]}
]
},
{
"name": "hair_front_right_rotation",
"parent": "hair",
"pivot": [0, 11, 0],
"rotation": [0, -144, 0]
},
{
"name": "hair_front_right",
"parent": "hair_front_right_rotation",
"pivot": [0, 11, 1.25],
"rotation": [-25, 0, 0],
"cubes": [
{"origin": [-1, 10, 1.25], "size": [2, 3, 0], "uv": [56, 3]}
]
},
{
"name": "hair_front_left_rotation",
"parent": "hair",
"pivot": [0, 11, 0],
"rotation": [0, 144, 0]
},
{
"name": "hair_front_left",
"parent": "hair_front_left_rotation",
"pivot": [0, 11, 1.25],
"rotation": [-25, 0, 0],
"cubes": [
{"origin": [-1, 10, 1.25], "size": [2, 3, 0], "uv": [60, 0]}
]
},
{
"name": "skirt",
"parent": "torso",
"pivot": [0, 5, 0]
},
{
"name": "skirt_left",
"parent": "skirt",
"pivot": [6, 5, 0],
"rotation": [0, 0, 55],
"cubes": [
{"origin": [6, 5, -6], "size": [4, 0, 12], "uv": [24, 0]}
]
},
{
"name": "skirt_right",
"parent": "skirt",
"pivot": [-6, 5, 0],
"rotation": [0, 0, -55],
"cubes": [
{"origin": [-10, 5, -6], "size": [4, 0, 12], "uv": [32, 0]}
]
},
{
"name": "skirt_front",
"parent": "skirt",
"pivot": [0, 5, -6],
"rotation": [55, 0, 0],
"cubes": [
{"origin": [-6, 5, -10], "size": [12, 0, 4], "uv": [20, 22]}
]
},
{
"name": "skirt_back",
"parent": "skirt",
"pivot": [0, 5, 6],
"rotation": [-55, 0, 0],
"cubes": [
{"origin": [-6, 5, 6], "size": [12, 0, 4], "uv": [-4, 22]}
]
},
{
"name": "foot_left",
"parent": "body",
"pivot": [2.5, 0.5, 0.5],
"pivot": [2.5, 1.5, 0.5],
"cubes": [
{"origin": [1, 0, -1.5], "size": [3, 1, 3], "uv": [49, 13]}
{"origin": [1, 0, -1.5], "size": [3, 2, 3], "uv": [0, 5]}
]
},
{
"name": "foot_right",
"parent": "body",
"pivot": [-2.5, 0.5, 0.5],
"pivot": [-2.5, 1.5, 0.5],
"cubes": [
{"origin": [-4, 0, -1.5], "size": [3, 1, 3], "uv": [37, 13]}
{"origin": [-4, 0, -1.5], "size": [3, 2, 3], "uv": [0, 0]}
]
}
]
@@ -76,10 +76,17 @@
"parent": "torso",
"pivot": [2.25, 8.75, -4.0125],
"cubes": [
{"origin": [1.75, 8.75, -4.015], "size": [1, 2, 0], "uv": [6, 12]},
{"origin": [1.25, 8.25, -4.01], "size": [2, 3, 0], "uv": [24, 15]}
]
},
{
"name": "pupil_left",
"parent": "eye_left",
"pivot": [2.25, 9.75, -4.015],
"cubes": [
{"origin": [1.75, 8.75, -4.015], "size": [1, 2, 0], "uv": [6, 12]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
@@ -101,10 +108,17 @@
"parent": "torso",
"pivot": [-2.25, 8.75, -4.0125],
"cubes": [
{"origin": [-2.75, 8.75, -4.015], "size": [1, 2, 0], "uv": [8, 7]},
{"origin": [-3.25, 8.25, -4.01], "size": [2, 3, 0], "uv": [0, 7]}
]
},
{
"name": "pupil_right",
"parent": "eye_right",
"pivot": [-2.25, 9.75, -4.015],
"cubes": [
{"origin": [-2.75, 8.75, -4.015], "size": [1, 2, 0], "uv": [8, 7]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
@@ -13,7 +13,7 @@
"bones": [
{
"name": "vikavolt",
"pivot": [0, 7, 0.75]
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
@@ -0,0 +1,425 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.minior",
"texture_width": 128,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
},
"bones": [
{
"name": "minior",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "minior",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "minior",
"pivot": [0, 18, 0],
"locators": {
"top": [0, 18, 0]
}
},
{
"name": "head_ai",
"parent": "minior",
"pivot": [0, 8.5, 0]
},
{
"name": "body",
"parent": "head_ai",
"pivot": [0, 8.5, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 9, -6.5],
"locators": {
"target": [0, 9, -6.5]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 9, 0],
"locators": {
"middle": [0, 9, 0]
}
},
{
"name": "core",
"parent": "body",
"pivot": [0, 8.5, 0],
"cubes": [
{"origin": [-5, 3.5, -5], "size": [10, 10, 10], "inflate": -0.25, "uv": [0, 1]}
]
},
{
"name": "locator_item_hat",
"parent": "core",
"pivot": [0, 13.5, 0],
"locators": {
"item_hat": [0, 13.5, 0]
}
},
{
"name": "face_main",
"parent": "core",
"pivot": [0, 8.5, -5.25]
},
{
"name": "locator_face",
"parent": "face_main",
"pivot": [0, 8.5, -5],
"locators": {
"face": [0, 8.5, -5]
}
},
{
"name": "locator_head",
"parent": "face_main",
"pivot": [0, 12, -4.75],
"locators": {
"head": [0, 12, -4.75]
}
},
{
"name": "locator_mouth",
"parent": "face_main",
"pivot": [0, 6.25, -5],
"locators": {
"mouth": [0, 6.25, -5]
}
},
{
"name": "locator_special",
"parent": "face_main",
"pivot": [0, 6.25, -5],
"locators": {
"special": [0, 6.25, -5]
}
},
{
"name": "face",
"parent": "face_main",
"pivot": [0, 8.5, -5]
},
{
"name": "locator_item_face",
"parent": "face",
"pivot": [0, 8.75, -5],
"locators": {
"item_face": [0, 8.75, -5]
}
},
{
"name": "mouth",
"parent": "face",
"pivot": [-0.05, 6.75, -4.9]
},
{
"name": "mouth_closed_smile",
"parent": "mouth",
"pivot": [0, 6.25, -5],
"cubes": [
{"origin": [-1.5, 6, -5], "size": [1, 1, 1], "uv": [113, 44]},
{"origin": [0.5, 6, -5], "size": [1, 1, 1], "uv": [118, 44]},
{"origin": [-0.5, 5.5, -5], "size": [1, 1, 1], "uv": [123, 44]}
]
},
{
"name": "mouth_closed_frown",
"parent": "mouth",
"pivot": [0, 6.25, -4],
"cubes": [
{"origin": [-1.5, 5.5, -4], "size": [1, 1, 1], "uv": [113, 47]},
{"origin": [0.5, 5.5, -4], "size": [1, 1, 1], "uv": [118, 47]},
{"origin": [-0.5, 6, -4], "size": [1, 1, 1], "uv": [123, 47]}
]
},
{
"name": "mouth_closed_neutral",
"parent": "mouth",
"pivot": [0, 6.5, -4],
"cubes": [
{"origin": [-1.5, 6, -4], "size": [3, 1, 1], "uv": [104, 44]}
]
},
{
"name": "mouth_open",
"parent": "mouth",
"pivot": [0, 6.5, -4],
"cubes": [
{"origin": [-0.5, 5.5, -4], "size": [1, 2, 1], "uv": [104, 40]}
]
},
{
"name": "mouth_open_small",
"parent": "mouth",
"pivot": [0, 6.5, -4],
"cubes": [
{"origin": [-0.5, 6, -4], "size": [1, 1, 1], "uv": [104, 37]}
]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 8.75, -5]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.5, 8.75, -5],
"cubes": [
{"origin": [1, 7.25, -5], "size": [3, 3, 1], "inflate": 0.01, "uv": [119, 35]},
{"origin": [2, 6.25, -5], "size": [4, 5, 0], "uv": [119, 29]},
{"origin": [1.5, 7.75, -5], "size": [2, 2, 1], "inflate": 0.02, "uv": [121, 40]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.5, 8.75, -5],
"cubes": [
{"origin": [-4, 7.25, -5], "size": [3, 3, 1], "inflate": 0.01, "uv": [110, 35]},
{"origin": [-6, 6.25, -5], "size": [4, 5, 0], "uv": [110, 29]},
{"origin": [-3.5, 7.75, -5], "size": [2, 2, 1], "inflate": 0.02, "uv": [112, 40]}
]
},
{
"name": "face_ditto",
"parent": "face_main",
"pivot": [0, 7.8, -4.65]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 8.55, -4.67],
"cubes": [
{"origin": [-4, 8.05, -4.67], "size": [8, 1, 0], "uv": [86, 31]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 8.55, -4.47],
"cubes": [
{"origin": [-4.5, 8.05, -4.57], "size": [9, 1, 0], "uv": [85, 33]},
{"origin": [-4, 8.55, -4.58], "size": [8, 1, 0], "uv": [86, 35]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 6.8, -4.65],
"cubes": [
{"origin": [-3.5, 6.05, -4.66], "size": [7, 1, 0], "uv": [87, 39]},
{"origin": [-4.5, 6.55, -4.66], "size": [9, 1, 0], "uv": [85, 37]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 6.55, -4.56],
"cubes": [
{"origin": [-4.5, 5.55, -4.56], "size": [9, 2, 0], "uv": [85, 41]}
]
},
{
"name": "arms",
"parent": "core",
"pivot": [0, 8.5, 0]
},
{
"name": "arm_top",
"parent": "arms",
"pivot": [0, 8.5, 0],
"cubes": [
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [31, 2]},
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [17, 30]},
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [44, 0]},
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [21, 29]}
]
},
{
"name": "locator_physcial",
"parent": "arm_top",
"pivot": [0, 17.25, 0],
"locators": {
"physical": [0, 17.25, 0]
}
},
{
"name": "arm_top_left",
"parent": "arms",
"pivot": [0, 8.5, 0],
"rotation": [0, 0, 67.5],
"cubes": [
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [67, 2]},
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [49, 30]},
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [80, 0]},
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [37, 29]}
]
},
{
"name": "arm_top_right",
"parent": "arms",
"pivot": [0, 8.5, 0],
"rotation": [0, 0, -67.5],
"cubes": [
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [49, 2]},
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [33, 30]},
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [62, 0]},
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [69, 29]}
]
},
{
"name": "locator_item",
"parent": "arm_top_right",
"pivot": [0, 17.25, 0],
"locators": {
"item": [0, 17.25, 0]
}
},
{
"name": "arm_bottom_right",
"parent": "arms",
"pivot": [0, 8.5, 0],
"rotation": [0, 0, -137.5],
"cubes": [
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [85, 2]},
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [81, 30]},
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [98, 0]},
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [85, 29]}
]
},
{
"name": "arm_bottom_left",
"parent": "arms",
"pivot": [0, 8.5, 0],
"rotation": [0, 0, 137.5],
"cubes": [
{"origin": [-2, 12, -2], "size": [4, 4, 4], "inflate": -0.25, "uv": [103, 2]},
{"origin": [2, 16, 2], "size": [-4, -4, -4], "uv": [65, 30]},
{"origin": [-1, 14.25, -1], "size": [2, 3, 2], "uv": [116, 0]},
{"origin": [1, 17.25, 1], "size": [-2, -1, -2], "inflate": -0.25, "uv": [53, 29]}
]
},
{
"name": "shell",
"parent": "body",
"pivot": [0, 8.5, 0]
},
{
"name": "shell_top_left",
"parent": "shell",
"pivot": [0, 8.5, -0.5],
"cubes": [
{"origin": [-0.5, 7, -5.5], "size": [6, 7, 0], "uv": [68, 56]},
{"origin": [-0.5, 14, -5.5], "size": [6, 0, 11], "uv": [3, 52]},
{"origin": [5.5, 7, -5.5], "size": [0, 7, 11], "uv": [1, 33]},
{"origin": [-0.5, 7, 5.5], "size": [6, 7, 0], "uv": [98, 56]},
{"origin": [1.75, 7.25, -5.25], "size": [3, 3, 1], "inflate": 0.26, "uv": [89, 20]}
]
},
{
"name": "shell_arm_top",
"parent": "shell_top_left",
"pivot": [1.5, 13, -1.5],
"cubes": [
{"origin": [-0.5, 14, -2.5], "size": [3, 2, 5], "inflate": 0.01, "uv": [93, 20]}
]
},
{
"name": "shell_arm_top_left",
"parent": "shell_top_left",
"pivot": [0, 8.5, -0.5],
"rotation": [0, 0, 67.5],
"cubes": [
{"origin": [-2.5, 13, -2.5], "size": [5, 3, 5], "uv": [62, 11]}
]
},
{
"name": "shell_top_right",
"parent": "shell",
"pivot": [0, 8.5, -0.5],
"cubes": [
{"origin": [-5.5, 6, -5.5], "size": [6, 8, 0], "uv": [54, 55]},
{"origin": [-5.5, 14, -5.5], "size": [6, 0, 11], "uv": [-10, 52]},
{"origin": [-5.5, 7, -5.5], "size": [0, 7, 11], "uv": [24, 33]},
{"origin": [-5.5, 8, 5.5], "size": [6, 6, 0], "uv": [98, 48]}
]
},
{
"name": "shell_arm_top2",
"parent": "shell_top_right",
"pivot": [1.5, 13, -1.5],
"cubes": [
{"origin": [-2.5, 14, -2.5], "size": [2, 2, 5], "inflate": 0.01, "uv": [110, 20]}
]
},
{
"name": "shell_arm_top_right",
"parent": "shell_top_right",
"pivot": [0, 8.5, -0.5],
"rotation": [0, 0, -67.5],
"cubes": [
{"origin": [-2.5, 13, -2.5], "size": [5, 3, 5], "uv": [41, 11]}
]
},
{
"name": "shell_bottom_left",
"parent": "shell",
"pivot": [4.5, 3, -4.5],
"cubes": [
{"origin": [-1.5, 3, -5.5], "size": [7, 4, 0], "uv": [82, 59]},
{"origin": [5.5, 3, -5.5], "size": [0, 5, 11], "uv": [47, 35]},
{"origin": [-0.5, 3, -5.5], "size": [6, 0, 11], "uv": [29, 52]},
{"origin": [-2.5, 3, 5.5], "size": [8, 6, 0], "uv": [111, 57]},
{"origin": [3.5, 7, -5.5], "size": [2, 2, 1], "inflate": 0.02, "uv": [105, 21]}
]
},
{
"name": "shell_arm_bottom_left",
"parent": "shell_bottom_left",
"pivot": [0, 8.5, -0.5],
"rotation": [0, 0, 137.5],
"cubes": [
{"origin": [-2.5, 13, -2.5], "size": [5, 3, 5], "uv": [104, 11]}
]
},
{
"name": "shell_bottom_right",
"parent": "shell",
"pivot": [-4.5, 3, -4.5],
"cubes": [
{"origin": [-5.5, 3, -5.5], "size": [0, 5, 11], "uv": [70, 35]},
{"origin": [-5.5, 3, -5.5], "size": [5, 4, 0], "uv": [84, 53]},
{"origin": [-5.5, 3, -5.5], "size": [6, 0, 11], "uv": [16, 52]},
{"origin": [-5.5, 3, 5.5], "size": [6, 5, 0], "uv": [113, 50]}
]
},
{
"name": "shell_arm_bottom_right",
"parent": "shell_bottom_right",
"pivot": [0, 8.5, -0.5],
"rotation": [0, 0, -137.5],
"cubes": [
{"origin": [-2.5, 13, -2.5], "size": [5, 3, 5], "uv": [83, 11]}
]
}
]
}
]
}
@@ -0,0 +1,64 @@
{
"portraitScale": 1.7,
"portraitTranslation": [-0.45, -0.13, 0],
"profileScale": 0.7,
"profileTranslation": [0, 0.66, 0],
"rootBone": "ekans",
"animations": {
"recoil": "q.bedrock_stateful('ekans', 'recoil')",
"cry": "q.bedrock_stateful('ekans', 'cry')"
},
"poses": {
"standing": {
"poseTypes": ["STAND", "PORTRAIT", "PROFILE", "FLOAT", "NONE"],
"isBattle": false,
"animations": [
"q.look('head_ai')",
"q.bedrock('ekans', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('ekans', 'blink')"
]
},
"battle-standing": {
"poseTypes": ["STAND"],
"isBattle": true,
"animations": [
"q.look('head_ai')",
"q.bedrock('ekans', 'battle_idle')"
],
"quirks": [
"q.bedrock_quirk('ekans', 'blink')"
]
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"condition": "!q.is_sprinting",
"animations": [
"q.look('head_ai')",
"q.bedrock('ekans', 'ground_walk')"
],
"quirks": [
"q.bedrock_quirk('ekans', 'blink')"
]
},
"running": {
"poseTypes": ["WALK", "SWIM"],
"condition": "q.is_sprinting",
"animations": [
"q.look('head_ai')",
"q.bedrock('ekans', 'ground_run')"
],
"quirks": [
"q.bedrock_quirk('ekans', 'blink')"
]
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {"cry": "q.bedrock_stateful('dummy', 'cry')"},
"animations": [
"q.bedrock('ekans', 'sleep')"
]
}
}
}

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