mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-22 15:16:25 -04:00
Compare commits
51
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2f002d630 | ||
|
|
5b9d5cbb55 | ||
|
|
ff890307c2 | ||
|
|
dda9d3e790 | ||
|
|
1acc02a2ec | ||
|
|
9a036a4c01 | ||
|
|
3cea6dd175 | ||
|
|
2fa053f833 | ||
|
|
ea4f858919 | ||
|
|
d86021e2a1 | ||
|
|
79faadef59 | ||
|
|
9b6629db7f | ||
|
|
d151a1ce65 | ||
|
|
d9ca7b483d | ||
|
|
708f7fc1b8 | ||
|
|
621db85845 | ||
|
|
b09066c580 | ||
|
|
7c45f28827 | ||
|
|
9c1b2cae22 | ||
|
|
16b2f81bd4 | ||
|
|
108f0e3d88 | ||
|
|
4344c127eb | ||
|
|
5955547c6f | ||
|
|
7a3a1cb8de | ||
|
|
1674cb0913 | ||
|
|
152ce4e923 | ||
|
|
3a6d024217 | ||
|
|
f2fcc5ba79 | ||
|
|
db0fb8e287 | ||
|
|
dae36a67d1 | ||
|
|
6f99862288 | ||
|
|
0377747e1e | ||
|
|
6bc974f90f | ||
|
|
aca53de259 | ||
|
|
41bde38727 | ||
|
|
a4b7ee3b38 | ||
|
|
154b653c57 | ||
|
|
04489bc969 | ||
|
|
25499b3e7a | ||
|
|
bb6bda54dc | ||
|
|
9f3dbdc2d8 | ||
|
|
932148338c | ||
|
|
309f674853 | ||
|
|
dc705c7720 | ||
|
|
9bfc577444 | ||
|
|
3ca6d350fe | ||
|
|
2997ce8457 | ||
|
|
ff279d8310 | ||
|
|
91d6fb62ba | ||
|
|
8f4a5b2015 | ||
|
|
07604c9a3b |
+46
-2
@@ -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:
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Spec Doc: https://docs.google.com/document/d/1hEKKrT4JEagJBykx-k9K2BoeNxiMGahUWXnf8YQ85xo/edit?tab=t.0
|
||||
Marshal: dhi_holo
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -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()) {
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.block.*
|
||||
import com.cobblemon.mod.common.block.LecternBlock
|
||||
import com.cobblemon.mod.common.block.appliances.*
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
|
||||
@@ -29,7 +28,12 @@ import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
|
||||
import com.cobblemon.mod.common.block.tmmachine.TMMachineBlock
|
||||
import com.cobblemon.mod.common.mixin.invoker.*
|
||||
import com.cobblemon.mod.common.mixin.invoker.BlocksInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.DoorBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.FireBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.PressurePlateBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.StairsBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.TrapdoorBlockInvoker
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.BlockPos
|
||||
@@ -653,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))
|
||||
@@ -687,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
|
||||
@@ -698,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))
|
||||
@@ -751,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 }))
|
||||
@@ -805,93 +809,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F).requiresCorrectToolForDrops()))
|
||||
|
||||
//Rotom Blocks
|
||||
//Oven
|
||||
@JvmField
|
||||
val COPPER_OVEN = create("copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.BLOCK)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_OVEN = create("exposed_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_OVEN = create("weathered_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_OVEN = create("oxidized_copper_oven", WeatheringCopperOvenBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_OVEN = create("waxed_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_OVEN)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_OVEN = create("waxed_exposed_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_OVEN)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_OVEN = create("waxed_weathered_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_OVEN)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_OVEN = create("waxed_oxidized_copper_oven", CopperOvenBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_OVEN)))
|
||||
//Washer
|
||||
@JvmField
|
||||
val COPPER_WASHER = create("copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.BLOCK)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_WASHER = create("exposed_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_WASHER = create("weathered_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_WASHER = create("oxidized_copper_washer", WeatheringCopperWasherBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_WASHER = create("waxed_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_WASHER)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_WASHER = create("waxed_exposed_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_WASHER)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_WASHER = create("waxed_weathered_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_WASHER)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_WASHER = create("waxed_oxidized_copper_washer", CopperWasherBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_WASHER)))
|
||||
//Fan
|
||||
@JvmField
|
||||
val COPPER_FAN = create("copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.DESTROY)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FAN = create("exposed_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FAN = create("weathered_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FAN = create("oxidized_copper_fan", WeatheringCopperFanBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_FAN).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FAN = create("waxed_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_FAN)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FAN = create("waxed_exposed_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_FAN)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FAN = create("waxed_weathered_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_FAN)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FAN = create("waxed_oxidized_copper_fan", CopperFanBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_FAN)))
|
||||
//Mower
|
||||
@JvmField
|
||||
val COPPER_MOWER = create("copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.NORMAL)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_MOWER = create("exposed_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_MOWER = create("weathered_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_MOWER = create("oxidized_copper_mower", WeatheringCopperMowerBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_MOWER = create("waxed_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_MOWER)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_MOWER = create("waxed_exposed_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_MOWER)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_MOWER = create("waxed_weathered_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_MOWER)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_MOWER = create("waxed_oxidized_copper_mower", CopperMowerBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_MOWER)))
|
||||
//Fridge
|
||||
@JvmField
|
||||
val COPPER_FRIDGE = create("copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.UNAFFECTED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0f, 6.0f).sound(SoundType.COPPER).pushReaction(PushReaction.BLOCK)))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FRIDGE = create("exposed_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.TERRACOTTA_LIGHT_GRAY)))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FRIDGE = create("weathered_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.WARPED_STEM)))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FRIDGE = create("oxidized_copper_fridge", WeatheringCopperFridgeBlock(WeatheringCopper.WeatherState.OXIDIZED, BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE).mapColor(MapColor.WARPED_NYLIUM)))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FRIDGE = create("waxed_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(COPPER_FRIDGE)))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FRIDGE = create("waxed_exposed_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(EXPOSED_COPPER_FRIDGE)))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FRIDGE = create("waxed_weathered_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(WEATHERED_COPPER_FRIDGE)))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FRIDGE = create("waxed_oxidized_copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.ofFullCopy(OXIDIZED_COPPER_FRIDGE)))
|
||||
|
||||
// TODO after 1.7
|
||||
// @JvmField
|
||||
// val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F)))
|
||||
@@ -959,57 +876,6 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
|
||||
SACCHARINE_LOG_SLATHERED to STRIPPED_SACCHARINE_LOG
|
||||
)
|
||||
/**Same idea as above, but for Copper Oxidation over time (or when inverted, scraping with an axe)*/
|
||||
fun oxidizingBlocks(): Map<Block, Block> = mapOf(
|
||||
//Ovens
|
||||
COPPER_OVEN to EXPOSED_COPPER_OVEN,
|
||||
EXPOSED_COPPER_OVEN to WEATHERED_COPPER_OVEN,
|
||||
WEATHERED_COPPER_OVEN to OXIDIZED_COPPER_OVEN,
|
||||
//Washers
|
||||
COPPER_WASHER to EXPOSED_COPPER_WASHER,
|
||||
EXPOSED_COPPER_WASHER to WEATHERED_COPPER_WASHER,
|
||||
WEATHERED_COPPER_WASHER to OXIDIZED_COPPER_WASHER,
|
||||
//Fans
|
||||
COPPER_FAN to EXPOSED_COPPER_FAN,
|
||||
EXPOSED_COPPER_FAN to WEATHERED_COPPER_FAN,
|
||||
WEATHERED_COPPER_FAN to OXIDIZED_COPPER_FAN,
|
||||
//Fridges
|
||||
COPPER_FRIDGE to EXPOSED_COPPER_FRIDGE,
|
||||
EXPOSED_COPPER_FRIDGE to WEATHERED_COPPER_FRIDGE,
|
||||
WEATHERED_COPPER_FRIDGE to OXIDIZED_COPPER_FRIDGE,
|
||||
//Mowers
|
||||
COPPER_MOWER to EXPOSED_COPPER_MOWER,
|
||||
EXPOSED_COPPER_MOWER to WEATHERED_COPPER_MOWER,
|
||||
WEATHERED_COPPER_MOWER to OXIDIZED_COPPER_MOWER
|
||||
)
|
||||
/**Same idea as above, but for waxing blocks with Honeycomb (or unwaxing them with an axe)*/
|
||||
fun waxingBlocks(): Map<Block, Block> = mapOf(
|
||||
//Ovens
|
||||
COPPER_OVEN to WAXED_COPPER_OVEN,
|
||||
EXPOSED_COPPER_OVEN to WAXED_EXPOSED_COPPER_OVEN,
|
||||
WEATHERED_COPPER_OVEN to WAXED_WEATHERED_COPPER_OVEN,
|
||||
OXIDIZED_COPPER_OVEN to WAXED_OXIDIZED_COPPER_OVEN,
|
||||
//Washers
|
||||
COPPER_WASHER to WAXED_COPPER_WASHER,
|
||||
EXPOSED_COPPER_WASHER to WAXED_EXPOSED_COPPER_WASHER,
|
||||
WEATHERED_COPPER_WASHER to WAXED_WEATHERED_COPPER_WASHER,
|
||||
OXIDIZED_COPPER_WASHER to WAXED_OXIDIZED_COPPER_WASHER,
|
||||
//Fans
|
||||
COPPER_FAN to WAXED_COPPER_FAN,
|
||||
EXPOSED_COPPER_FAN to WAXED_EXPOSED_COPPER_FAN,
|
||||
WEATHERED_COPPER_FAN to WAXED_WEATHERED_COPPER_FAN,
|
||||
OXIDIZED_COPPER_FAN to WAXED_OXIDIZED_COPPER_FAN,
|
||||
//Fridges
|
||||
COPPER_FRIDGE to WAXED_COPPER_FRIDGE,
|
||||
EXPOSED_COPPER_FRIDGE to WAXED_EXPOSED_COPPER_FRIDGE,
|
||||
WEATHERED_COPPER_FRIDGE to WAXED_WEATHERED_COPPER_FRIDGE,
|
||||
OXIDIZED_COPPER_FRIDGE to WAXED_OXIDIZED_COPPER_FRIDGE,
|
||||
//Mowers
|
||||
COPPER_MOWER to WAXED_COPPER_MOWER,
|
||||
EXPOSED_COPPER_MOWER to WAXED_EXPOSED_COPPER_MOWER,
|
||||
WEATHERED_COPPER_MOWER to WAXED_WEATHERED_COPPER_MOWER,
|
||||
OXIDIZED_COPPER_MOWER to WAXED_OXIDIZED_COPPER_MOWER
|
||||
)
|
||||
|
||||
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(BlockBehaviour.Properties.of().mapColor(apricorn.mapColor()).randomTicks().strength(Blocks.OAK_LOG.defaultDestroyTime(), Blocks.OAK_LOG.explosionResistance).sound(SoundType.WOOD).noOcclusion(), apricorn))
|
||||
|
||||
|
||||
@@ -1517,87 +1517,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val BLANK_TM = this.create("blank_tm", CobblemonItem(Item.Properties()))
|
||||
|
||||
@JvmField
|
||||
val COPPER_OVEN = this.create("copper_oven", BlockItem(CobblemonBlocks.COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_OVEN = this.create("exposed_copper_oven", BlockItem(CobblemonBlocks.EXPOSED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_OVEN = this.create("weathered_copper_oven", BlockItem(CobblemonBlocks.WEATHERED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_OVEN = this.create("oxidized_copper_oven", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_OVEN = this.create("waxed_copper_oven", BlockItem(CobblemonBlocks.WAXED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_OVEN = this.create("waxed_exposed_copper_oven", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_OVEN = this.create("waxed_weathered_copper_oven", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_OVEN = this.create("waxed_oxidized_copper_oven", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_OVEN, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_WASHER = this.create("copper_washer", BlockItem(CobblemonBlocks.COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_WASHER = this.create("exposed_copper_washer", BlockItem(CobblemonBlocks.EXPOSED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_WASHER = this.create("weathered_copper_washer", BlockItem(CobblemonBlocks.WEATHERED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_WASHER = this.create("oxidized_copper_washer", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_WASHER = this.create("waxed_copper_washer", BlockItem(CobblemonBlocks.WAXED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_WASHER = this.create("waxed_exposed_copper_washer", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_WASHER = this.create("waxed_weathered_copper_washer", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_WASHER = this.create("waxed_oxidized_copper_washer", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_WASHER, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_FAN = this.create("copper_fan", BlockItem(CobblemonBlocks.COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FAN = this.create("exposed_copper_fan", BlockItem(CobblemonBlocks.EXPOSED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FAN = this.create("weathered_copper_fan", BlockItem(CobblemonBlocks.WEATHERED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FAN = this.create("oxidized_copper_fan", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FAN = this.create("waxed_copper_fan", BlockItem(CobblemonBlocks.WAXED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FAN = this.create("waxed_exposed_copper_fan", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FAN = this.create("waxed_weathered_copper_fan", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FAN = this.create("waxed_oxidized_copper_fan", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_FAN, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_MOWER = this.create("copper_mower", BlockItem(CobblemonBlocks.COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_MOWER = this.create("exposed_copper_mower", BlockItem(CobblemonBlocks.EXPOSED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_MOWER = this.create("weathered_copper_mower", BlockItem(CobblemonBlocks.WEATHERED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_MOWER = this.create("oxidized_copper_mower", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_MOWER = this.create("waxed_copper_mower", BlockItem(CobblemonBlocks.WAXED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_MOWER = this.create("waxed_exposed_copper_mower", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_MOWER = this.create("waxed_weathered_copper_mower", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_MOWER = this.create("waxed_oxidized_copper_mower", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_MOWER, Item.Properties()))
|
||||
@JvmField
|
||||
val COPPER_FRIDGE = this.create("copper_fridge", BlockItem(CobblemonBlocks.COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val EXPOSED_COPPER_FRIDGE = this.create("exposed_copper_fridge", BlockItem(CobblemonBlocks.EXPOSED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WEATHERED_COPPER_FRIDGE = this.create("weathered_copper_fridge", BlockItem(CobblemonBlocks.WEATHERED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val OXIDIZED_COPPER_FRIDGE = this.create("oxidized_copper_fridge", BlockItem(CobblemonBlocks.OXIDIZED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_COPPER_FRIDGE = this.create("waxed_copper_fridge", BlockItem(CobblemonBlocks.WAXED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_EXPOSED_COPPER_FRIDGE = this.create("waxed_exposed_copper_fridge", BlockItem(CobblemonBlocks.WAXED_EXPOSED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_WEATHERED_COPPER_FRIDGE = this.create("waxed_weathered_copper_fridge", BlockItem(CobblemonBlocks.WAXED_WEATHERED_COPPER_FRIDGE, Item.Properties()))
|
||||
@JvmField
|
||||
val WAXED_OXIDIZED_COPPER_FRIDGE = this.create("waxed_oxidized_copper_fridge", BlockItem(CobblemonBlocks.WAXED_OXIDIZED_COPPER_FRIDGE, Item.Properties()))
|
||||
|
||||
// Type Gems
|
||||
@JvmField
|
||||
val NORMAL_GEM = this.create("normal_gem", GemItem(Item.Properties(), CobblemonBlocks.TYPE_GEM_CLUSTER_NORMAL))
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
|
||||
+12
-1
@@ -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)
|
||||
}
|
||||
+1
-1
@@ -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()}")
|
||||
}
|
||||
}
|
||||
@@ -1,87 +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.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: All the Fan appliance stuff
|
||||
//TODO: Able to place the Fan on Walls, models and hitbox are there (blockstate would need edits to support it)
|
||||
open class CopperFanBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperFanBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperFanBlock) }
|
||||
//val FACE = //TODO: Floor/Wall
|
||||
val POWER = BlockStateProperties.POWER;
|
||||
val PUSH = BooleanProperty.create("push")
|
||||
|
||||
val FLOOR_HITBOX = Shapes.or(
|
||||
Shapes.box(0.0625, 0.125, 0.4375, 0.9375, 1.0, 0.5625),
|
||||
Shapes.box(0.375, 0.0, 0.375, 0.625, 0.125, 0.625))
|
||||
val WALL_HITBOX = Shapes.box(0.0625, 0.0625, 0.875, 0.9375, 0.9375, 1.0)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
//.setValue(FACE, AttachFace.FLOOR)
|
||||
.setValue(POWER, 0)
|
||||
.setValue(PUSH, true) //If True, fan pushes entities, If False, fan is cosmetic only
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperFanBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, /*FACE,*/ POWER, PUSH)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, FLOOR_HITBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
return getCollisionShape(state, level, pos, context)
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
}
|
||||
-153
@@ -1,153 +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.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.LevelReader
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: Oxidation/Waxing/Scraping not breaking the blocks
|
||||
//TODO: All the Fridge appliance stuff
|
||||
open class CopperFridgeBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperFridgeBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperFridgeBlock) }
|
||||
val HALF: EnumProperty<DoubleBlockHalf> = BlockStateProperties.DOUBLE_BLOCK_HALF
|
||||
val POWERED = BooleanProperty.create("powered")
|
||||
|
||||
val LOWER_HITBOX = Shapes.or(
|
||||
Shapes.box(0.0625, 0.0, 0.125, 0.9375, 0.0625, 0.9375),
|
||||
Shapes.box(0.0, 0.0625, 0.0625, 1.0, 1.0, 1.0))
|
||||
val UPPER_HITBOX = Shapes.or(
|
||||
Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0),
|
||||
Shapes.box(0.25, 0.125, 0.0, 0.375, 0.3125, 0.0625),
|
||||
Shapes.box(0.625, 0.125, 0.0, 0.75, 0.3125, 0.0625))
|
||||
val UPPER_COLLISSIONBOX = Shapes.box(0.0, 0.0, 0.0625, 1.0, 1.0, 1.0)
|
||||
//The handles get ignored by entity collission, because it feels nicer, but still count as part of the hitbox
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(HALF, DoubleBlockHalf.LOWER)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(POWERED, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperFridgeBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, HALF, WATERLOGGED, POWERED)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
|
||||
val isFridge = neighborState.`is`(this)
|
||||
val half = state.getValue(HALF)
|
||||
if (!isFridge && half == DoubleBlockHalf.UPPER && neighborPos == pos.below()) {
|
||||
return Blocks.AIR.defaultBlockState()
|
||||
} else if (!isFridge && half == DoubleBlockHalf.LOWER && neighborPos == pos.above()) {
|
||||
return Blocks.AIR.defaultBlockState()
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
|
||||
rotateShape(Direction.NORTH, direction, LOWER_HITBOX)
|
||||
} else {
|
||||
rotateShape(Direction.NORTH, direction, UPPER_COLLISSIONBOX)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
|
||||
rotateShape(Direction.NORTH, direction, LOWER_HITBOX)
|
||||
} else {
|
||||
rotateShape(Direction.NORTH, direction, UPPER_HITBOX)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setPlacedBy(world: Level, pos: BlockPos, state: BlockState, placer: LivingEntity?, itemStack: ItemStack) {
|
||||
world.setBlock(pos.above(),
|
||||
state
|
||||
.setValue(HALF, DoubleBlockHalf.UPPER)
|
||||
.setValue(WATERLOGGED, world.getFluidState((pos.above())).type == Fluids.WATER)
|
||||
, 3)
|
||||
world.blockUpdated(pos, Blocks.AIR)
|
||||
state.updateNeighbourShapes(world, pos, 3)
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(blockPlaceContext: BlockPlaceContext): BlockState? {
|
||||
val abovePosition = blockPlaceContext.clickedPos.above()
|
||||
val world = blockPlaceContext.level
|
||||
if (world.getBlockState(abovePosition).canBeReplaced(blockPlaceContext) && !world.isOutsideBuildHeight(abovePosition)) {
|
||||
return defaultBlockState()
|
||||
.setValue(FACING, blockPlaceContext.horizontalDirection.opposite)
|
||||
.setValue(HALF, DoubleBlockHalf.LOWER)
|
||||
.setValue(WATERLOGGED, blockPlaceContext.level.getFluidState(blockPlaceContext.clickedPos).type == Fluids.WATER)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun canSurvive(state: BlockState, world: LevelReader, pos: BlockPos): Boolean {
|
||||
val blockPos = pos.below()
|
||||
val blockState = world.getBlockState(blockPos)
|
||||
return if (state.getValue(HALF) == DoubleBlockHalf.LOWER) blockState.isFaceSturdy(world, blockPos, Direction.UP) else blockState.`is`(this)
|
||||
}
|
||||
|
||||
override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player): BlockState {
|
||||
if (!world.isClientSide && player.isCreative) {
|
||||
var blockPos: BlockPos = BlockPos.ZERO
|
||||
var blockState: BlockState = state
|
||||
val half = state.getValue(HALF)
|
||||
if (half == DoubleBlockHalf.UPPER && world.getBlockState(pos.below().also { blockPos = it }).also { blockState = it }.`is`(state.block) && blockState.getValue(
|
||||
HALF
|
||||
) == DoubleBlockHalf.LOWER) {
|
||||
val blockState2 = if (blockState.fluidState.`is`(Fluids.WATER)) Blocks.WATER.defaultBlockState() else Blocks.AIR.defaultBlockState()
|
||||
world.setBlock(blockPos, blockState2, UPDATE_ALL or UPDATE_SUPPRESS_DROPS)
|
||||
world.levelEvent(player, LevelEvent.PARTICLES_DESTROY_BLOCK, blockPos, getId(blockState))
|
||||
}
|
||||
}
|
||||
return super.playerWillDestroy(world, pos, state, player)
|
||||
}
|
||||
}
|
||||
@@ -1,92 +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.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: All the Mower appliance stuff
|
||||
open class CopperMowerBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperMowerBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperMowerBlock) }
|
||||
val TRIGGERED = BooleanProperty.create("triggered")
|
||||
|
||||
val COLLISIONBOX = Shapes.or(
|
||||
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
|
||||
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
|
||||
Shapes.box(0.125, 0.0, 0.1875, 0.875, 0.3125, 0.5),
|
||||
//The next three lines are just so the handle does have collision, it feels awkward without it but it looks bad as hitbox
|
||||
Shapes.box(0.375, 0.375, 0.375, 0.625, 0.625, 0.5625),
|
||||
Shapes.box(0.4375, 0.5625, 0.5, 0.5625, 0.875, 0.625),
|
||||
Shapes.box(0.25, 0.875, 0.5625, 0.75, 1.0, 0.6875)
|
||||
)
|
||||
val HITBOX = Shapes.or(
|
||||
Shapes.box(0.1875, 0.0, 0.0, 0.8125, 0.375, 0.625),
|
||||
Shapes.box(0.0625, 0.0, 0.625, 0.9375, 0.625, 1.0),
|
||||
Shapes.box(0.125, 0.0, 0.1875, 0.875, 0.3125, 0.5)
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(TRIGGERED, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperMowerBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, TRIGGERED)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, COLLISIONBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, HITBOX)
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
}
|
||||
@@ -1,88 +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.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
//TODO: All the Oven appliance stuff - Good Luck Coders
|
||||
open class CopperOvenBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperOvenBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperOvenBlock) }
|
||||
val EJECTING = BooleanProperty.create("ejecting")
|
||||
val COOKING = EnumProperty.create("cooking", CookingState::class.java)
|
||||
|
||||
val HITBOX = Shapes.box(0.0625, 0.0, 0.3125, 0.9375, 0.625, 0.9375)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(COOKING, CookingState.CLOSED)
|
||||
.setValue(EJECTING, false)
|
||||
)
|
||||
}
|
||||
enum class CookingState : StringRepresentable {
|
||||
CLOSED, //Door is closed
|
||||
OPEN, //Door is open
|
||||
COOKING; //Door is locked closed and the light level is cranked up, as long as the block is powered by redstone. Acts as closed lid in the original Campfire Pot
|
||||
override fun getSerializedName(): String = this.name.lowercase()
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperOvenBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, COOKING, EJECTING)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, HITBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
return getCollisionShape(state, level, pos, context).singleEncompassing()
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
}
|
||||
@@ -1,78 +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.block.appliances
|
||||
|
||||
import com.cobblemon.mod.common.util.rotateShape
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.StateDefinition
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty
|
||||
import net.minecraft.world.level.material.FluidState
|
||||
import net.minecraft.world.level.material.Fluids
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
|
||||
open class CopperWasherBlock(settings: Properties) : HorizontalDirectionalBlock(settings), SimpleWaterloggedBlock {
|
||||
|
||||
companion object {
|
||||
val CODEC: MapCodec<CopperWasherBlock> = RecordCodecBuilder.mapCodec {
|
||||
it.group(propertiesCodec()).apply(it, ::CopperWasherBlock) }
|
||||
val POWERED = BooleanProperty.create("powered")
|
||||
|
||||
val HITBOX = Shapes.box(0.0625, 0.0, 0.125, 0.9375, 1.0, 1.0)
|
||||
}
|
||||
|
||||
init {
|
||||
registerDefaultState(stateDefinition.any()
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(WATERLOGGED, false)
|
||||
.setValue(POWERED, false)
|
||||
)
|
||||
}
|
||||
|
||||
override fun codec(): MapCodec<CopperWasherBlock> = CODEC
|
||||
|
||||
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||
builder.add(HORIZONTAL_FACING, WATERLOGGED, POWERED)
|
||||
}
|
||||
|
||||
override fun getFluidState(blockState: BlockState): FluidState? = if (blockState.getValue(WATERLOGGED)) Fluids.WATER.getSource(false) else super.getFluidState(blockState)
|
||||
|
||||
override fun updateShape(state: BlockState, direction: Direction, neighborState: BlockState, world: LevelAccessor, pos: BlockPos, neighborPos: BlockPos): BlockState {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world))
|
||||
}
|
||||
return if (state.getValue(HORIZONTAL_FACING).opposite == direction && !state.canSurvive(world, pos)) Blocks.AIR.defaultBlockState()
|
||||
else super.updateShape(state, direction, neighborState, world, pos, neighborPos)
|
||||
}
|
||||
|
||||
override fun getCollisionShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
val direction = state.getValue(HORIZONTAL_FACING)
|
||||
return rotateShape(Direction.NORTH, direction, HITBOX)
|
||||
}
|
||||
|
||||
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
return getCollisionShape(state, level, pos, context).singleEncompassing()
|
||||
}
|
||||
|
||||
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||
val fluidState = context.level.getFluidState(context.clickedPos)
|
||||
return super.getStateForPlacement(context)?.setValue(HORIZONTAL_FACING, context.horizontalDirection.opposite)?.setValue(WATERLOGGED, fluidState.type === Fluids.WATER)
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +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.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperFanBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperFanBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +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.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
|
||||
|
||||
class WeatheringCopperFridgeBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperFridgeBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
if (state.getValue(HALF) == DoubleBlockHalf.LOWER) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +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.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperMowerBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperMowerBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +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.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperOvenBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperOvenBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +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.block.appliances
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.block.WeatheringCopper
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
class WeatheringCopperWasherBlock(val weatherState: WeatheringCopper.WeatherState, properties: Properties) :
|
||||
CopperWasherBlock(properties), WeatheringCopper {
|
||||
|
||||
override fun randomTick(state: BlockState?, level: ServerLevel?, pos: BlockPos?, random: RandomSource?) {
|
||||
this.changeOverTime(state, level, pos, random)
|
||||
}
|
||||
|
||||
override fun isRandomlyTicking(state: BlockState): Boolean {
|
||||
return WeatheringCopper.getNext(state.getBlock()).isPresent()
|
||||
}
|
||||
|
||||
override fun getAge(): WeatheringCopper.WeatherState {
|
||||
return this.weatherState
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -414,16 +415,7 @@ object CobblemonClient {
|
||||
CobblemonBlocks.NEVER_MELT_ICE,
|
||||
CobblemonBlocks.WIDE_LENS,
|
||||
CobblemonBlocks.ZOOM_LENS,
|
||||
CobblemonBlocks.SCOPE_LENS,
|
||||
|
||||
CobblemonBlocks.COPPER_FAN,
|
||||
CobblemonBlocks.EXPOSED_COPPER_FAN,
|
||||
CobblemonBlocks.WEATHERED_COPPER_FAN,
|
||||
CobblemonBlocks.OXIDIZED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_EXPOSED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_WEATHERED_COPPER_FAN,
|
||||
CobblemonBlocks.WAXED_OXIDIZED_COPPER_FAN
|
||||
CobblemonBlocks.SCOPE_LENS
|
||||
)
|
||||
|
||||
this.createBoatModelLayers()
|
||||
@@ -445,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)
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -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
|
||||
|
||||
+72
-9
@@ -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
|
||||
|
||||
|
||||
+27
-126
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-65
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
+100
@@ -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
|
||||
}
|
||||
}
|
||||
+151
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
+143
@@ -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())
|
||||
}
|
||||
+48
@@ -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."))
|
||||
}
|
||||
+123
@@ -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)
|
||||
}
|
||||
+379
@@ -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
|
||||
}
|
||||
+571
@@ -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>
|
||||
}
|
||||
+64
@@ -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()
|
||||
}
|
||||
}
|
||||
+17
-8
@@ -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)
|
||||
|
||||
+4
-3
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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) }
|
||||
|
||||
-104
@@ -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")
|
||||
}
|
||||
-63
@@ -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")
|
||||
}
|
||||
-66
@@ -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")
|
||||
}
|
||||
-75
@@ -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>
|
||||
}
|
||||
-66
@@ -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")
|
||||
}
|
||||
-95
@@ -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
|
||||
}
|
||||
-80
@@ -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
|
||||
}
|
||||
-72
@@ -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
|
||||
}
|
||||
-91
@@ -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
|
||||
}
|
||||
-102
@@ -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
|
||||
}
|
||||
-10
@@ -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)
|
||||
|
||||
+31
@@ -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
|
||||
}
|
||||
}
|
||||
+74
@@ -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
|
||||
}
|
||||
+7
-2
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,47 +487,6 @@ object CobblemonItemGroups {
|
||||
entries.accept(CobblemonItems.PINK_PLAQUE)
|
||||
|
||||
CobblemonItems.campfire_pots.forEach(entries::accept)
|
||||
|
||||
entries.accept(CobblemonItems.COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.COPPER_FAN)
|
||||
entries.accept(CobblemonItems.COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.EXPOSED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WEATHERED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.OXIDIZED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_EXPOSED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_WEATHERED_COPPER_FRIDGE)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_OVEN)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_WASHER)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_FAN)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_MOWER)
|
||||
entries.accept(CobblemonItems.WAXED_OXIDIZED_COPPER_FRIDGE)
|
||||
}
|
||||
|
||||
private fun consumableEntries(displayContext: ItemDisplayParameters, entries: Output) {
|
||||
|
||||
+100
@@ -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
|
||||
|
||||
+16
-3
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -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())
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
+592
-266
@@ -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]}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1952
-413
File diff suppressed because it is too large
Load Diff
+916
-761
File diff suppressed because it is too large
Load Diff
+966
-764
File diff suppressed because it is too large
Load Diff
+1061
-598
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -833,7 +833,7 @@
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.125": {
|
||||
"effect": "pokemon.diglett_alolan.cry"
|
||||
"effect": "pokemon.diglett.cry"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+171
-130
@@ -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]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+919
-140
File diff suppressed because it is too large
Load Diff
+3188
-114
File diff suppressed because it is too large
Load Diff
+892
-48
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9798
-401
File diff suppressed because it is too large
Load Diff
+21
-21
@@ -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]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
@@ -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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+886
-159
File diff suppressed because it is too large
Load Diff
+82
@@ -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]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+358
-157
@@ -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]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+513
-341
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+629
-389
File diff suppressed because it is too large
Load Diff
+629
-389
File diff suppressed because it is too large
Load Diff
-335
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+632
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+632
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+310
-247
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user