Compare commits

..
Author SHA1 Message Date
Guilherme Pereira 89a1da273e remove hsl colour mixing 2025-11-25 21:30:54 -03:00
Paul 64c7b7da67 Changelog 2025-11-24 19:28:56 +10:00
Paul 5209a77be2 Merge remote-tracking branch 'origin/main' into attempted-jvm-fix 2025-11-24 19:25:49 +10:00
Paul 567a5ff617 Try to fix crazy JVM issue 2025-11-24 15:28:49 +10:00
221 changed files with 5390 additions and 13936 deletions

No files matched your search

-16
View File
@@ -1,16 +0,0 @@
### Additions
### Changes
- Wild Pokémon now reliably have at least one offensive move, if they can have offensive moves at that level.
### Fixes
### Developer
### Molang & Datapacks
- Added `moveset_builders` datapack folder for different styles of movesets.
- Added `party_pools` datapack folder for defining groups of Pokémon for the purposes of complex NPC party definitions.
- Added `party_compositions` datapack folder for arranging parties on NPCs that rely on party pools.
- Added `composed_pool` NPC party provider type which combines a party pool with a party composition to create more complex NPC parties.
### Particles
+17 -7
View File
@@ -1,16 +1,27 @@
# Changelog
## [1.7.2 (MONTH Xth, YEAR)](#1-7-2)
## [1.7.1 (MONTH xth, 2025)](#1-7-1)
### Additions
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader.
- Added brewing recipe for Throat Spray.
### Changes
- Converted the riding freelook button to a configurable keybinding.
- Reduced the cost of the Vivichoke Seed trade with the Wandering Trader.
### Fixes
- Fixed orientation not getting reset after crashing while flying and getting back on the Pokémon.
- Fixed Furfrou not being trimmable on NeoForge.
- Fixed honey from Saccharine Leaves being harvestable at less than the max age.
- Items given from interacting with Saccharine Leaves are placed in the active hotbar slot if possible.
- Fix all Pokémon being saved to chunks and never despawning.
- Prevent displaying ride controls overlay to passengers.
- Fixed Poké Snack spawning sounds not coming from the block.
- Fix player suffocation on vanilla mounts experienced on some worlds.
- Stop passengers from hearing the shiny noise of a ridden shiny Pokémon.
- Ponigiri can no longer be eaten at full hunger.
- Medicinal Brew's Campfire Pot recipe now correctly displays that it can be made using an empty glass bottle or a filled bottle,
- Fix incorrect camera pivot on Bird, Jet, and Dolphin mounts.
- Fixed Combees not depositing honey upon leaving a hive if they entered with nectar.
- Fixed a crash involving Combees and hives.
- Fixed a crash when opening a PC box with certain wallpapers while using *VulkanMod*.
- Fixed friendship resetting to the default value when evolving a Pokémon.
- Fixed a graphics crash that could occur on some machines when campfires were nearby.
### Developer
@@ -19,4 +30,3 @@
### Particles
### Localization
- Updated translations for:
-61
View File
@@ -1,61 +0,0 @@
# Changelog
## [1.7.1 (November 29th, 2025)](#1-7-1)
### Additions
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader.
- Added brewing recipe for Throat Spray.
- Added vanilla sprinting's field of view change to Pokémon land mounts.
- Added a customizable keybind for the riding freelook button.
- Added double tap to sprint on land mounts.
### Changes
- Made Jet pitch turning 1.5x faster across all Pokémon.
- Party Pokémon now attack only mobs that are attacking their owner, instead of randomly targeting unrelated mobs and getting themselves hurt.
- Reduced the cost of the Vivichoke Seed trade with the Wandering Trader.
### Fixes
- Fixed incorrect camera pivot on Bird, Jet, and Dolphin mounts, leading to some disorienting riding.
- Fixed players suffocating while on vanilla mounts.
- Fixed a graphics crash that could occur on some machines when campfire pots were nearby.
- Fixed ride controls overlay being displayed to passengers. The passengers probably don't need to know about those.
- Fixed mount jumping so that it doesn't switch back to ground animations.
- Fixed ridden Pokémon land collision and some issues around stepping up blocks. Land mounts are smoother overall now.
- Fixed Furfrou's pink and magenta trims being swapped. Only a man could make that mistake.
- Fixed friendship being reset to the default value when evolving a Pokémon.
- Fixed Combees not depositing honey upon leaving a hive if they entered it with nectar.
- Fixed pastured Combees not moving during the night or in rain.
- Fixed a case in which a Combee might try to path to a flower that no longer exists.
- Fixed Combees attempting to enter a full hive.
- Fixed a crash involving Combees and hives. 500 bee bugs. Bugged bees? We can be bees. Mark, this is good news.
- Fixed a crash related to NPC navigation.
- Fixed a crash when opening a PC box with certain wallpapers while using *VulkanMod*.
- Fixed a crash when you place a block in the way of hearty grains 2nd block.
- Fixed passengers hearing the shiny noise of a ridden shiny Pokémon.
- Ponigiri can no longer be eaten at full hunger.
- Fixed Poké Snack spawning sounds not coming from the block.
- Medicinal Brew's Campfire Pot recipe now correctly displays that it can be made using an empty glass bottle or a filled bottle.
- Fixed glass bottle not being returned when slathering honey on a saccharine leaf block.
- Fixed saccharine hanging signs sometimes dropping their oak wood counterpart when being broken.
- Fixed a bunch of incompatibilities with NeoForge mods.
- Fixed a bug where wind charges hitting pasture blocks would recall all Pokémon in it.
- Fixed the Home on the Range advancement triggering when opening the Pokémon interaction wheel.
- Fixed recipes that use concrete not working on NeoForge.
- Fixed Boltund's model.
- Fixed Cyclizar's textures.
### Developer
### Molang & Datapacks
- Removed automatic generation of PC wallpaper screen glow if no asset is provided; it is now optional.
- This is because there's no practical way to do this without blowing up things like *VulkanMod*.
### Particles
### Localization
- Updated translations for:
- French
- Japanese
- Korean
- Brazilian Portuguese
- Simplified Chinese
- Traditional Chinese
@@ -0,0 +1,38 @@
/*
* 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;
import com.cobblemon.mod.common.block.PreEmptsExplosion;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(value = Explosion.class)
public class ExplosionMixin {
@Redirect(
method = "finalizeExplosion",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
ordinal = 0
)
)
public BlockState cobblemon$whenExploded(Level world, BlockPos pos) {
BlockState blockState = world.getBlockState(pos);
if(blockState.getBlock() instanceof PreEmptsExplosion preExplosionBlock) {
preExplosionBlock.whenExploded(world, blockState, pos);
}
return blockState;
}
}
@@ -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;
import net.minecraft.stats.RecipeBookSettings;
import net.minecraft.world.inventory.RecipeBookType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(RecipeBookSettings.class)
public class RecipeBookSettingsMixin {
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
@Inject(method = "<init>", at = @At("TAIL"))
private void cobblemon$init(CallbackInfo ci) {
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
}
}
@@ -6,9 +6,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.fabric.mixin;
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
import net.minecraft.world.inventory.RecipeBookType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -41,9 +40,7 @@ public class RecipeBookTypeMixin {
)
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
ArrayList<RecipeBookType> types = new ArrayList<>(List.of($VALUES));
// if you change or add any of these, neoforge uses a separate mechanism
// check enumextensions.json and `CobblemonEnumExtensions`
types.add(cobblemon$createBookType(CobblemonRecipeBookTypes.COOKING_POT_NAME, $VALUES.length));
types.add(cobblemon$createBookType("COOKING_POT", $VALUES.length));
$VALUES = types.toArray(RecipeBookType[]::new);
}
}
@@ -6,11 +6,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.fabric.mixin;
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.CobblemonItems;
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
import com.cobblemon.mod.common.CobblemonRecipeCategories;
import com.google.common.collect.ImmutableList;
import net.minecraft.client.RecipeBookCategories;
@@ -50,19 +49,17 @@ public class RecipeBookCategoriesMixin {
)
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
ArrayList<RecipeBookCategories> types = new ArrayList<>(List.of($VALUES));
// if you change or add any of these, neoforge uses a separate mechanism
// check enumextensions.json and `CobblemonEnumExtensions`
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
types.add(cobblemon$createCategory("COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
types.add(cobblemon$createCategory("COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
types.add(cobblemon$createCategory("COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
types.add(cobblemon$createCategory("COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
types.add(cobblemon$createCategory("COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
$VALUES = types.toArray(RecipeBookCategories[]::new);
}
@Inject(method = "getCategories", at = @At("HEAD"), cancellable = true)
private static void modifyCategories(RecipeBookType recipeBookType, CallbackInfoReturnable<List<RecipeBookCategories>> cir) {
if (recipeBookType == CobblemonRecipeBookTypes.INSTANCE.getCOOKING_POT()) {
if (recipeBookType == RecipeBookType.valueOf("COOKING_POT")) {
List var10000 = ImmutableList.of(
CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory(),
CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory(),
@@ -50,8 +50,16 @@ public abstract class EntityMixin {
)
)
public boolean cobblemon$forceOnGroundForStepUp(Entity entity, Operation<Boolean> original) {
if (entity instanceof PokemonEntity vehicle && entity.hasControllingPassenger()) {
return true;
if (entity instanceof PokemonEntity && entity.hasControllingPassenger()) {
BlockPos below = entity.blockPosition().below();
Level level = entity.level();
var blockStateBelow = level.getBlockState(below);
boolean isAirOrLiquid = blockStateBelow.isAir() || !blockStateBelow.getFluidState().isEmpty();
boolean canSupportEntity = blockStateBelow.isFaceSturdy(level, below, Direction.UP);
boolean standingOnSolid = canSupportEntity && !isAirOrLiquid;
if (standingOnSolid) {
return true;
}
}
return original.call(entity);
}
@@ -215,7 +215,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
@@ -1,55 +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
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.moves.MoveSelector
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.MovesetBuilderAdapter
import com.cobblemon.mod.common.util.adapters.StringToObjectAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
object CobblemonMovesetBuilders : JsonDataRegistry<MovesetBuilder> {
override val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(MovesetBuilder::class.java, MovesetBuilderAdapter)
.registerTypeAdapter(MoveSelector::class.java, StringToObjectAdapter(MoveSelector.selectors))
.create()
override val typeToken = TypeToken.get(MovesetBuilder::class.java)
override val resourcePath = "moveset_builders"
override val id: ResourceLocation = cobblemonResource("moveset_builders")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<CobblemonMovesetBuilders>()
val movesetBuilders = mutableMapOf<ResourceLocation, MovesetBuilder>()
fun getOrThrow(id: ResourceLocation): MovesetBuilder {
return movesetBuilders[id]
?: throw IllegalArgumentException("Unknown MovesetBuilder id: $id")
}
override fun sync(player: ServerPlayer) { /* These don't sync. But what if they did? Nah probably shouldn't sync. */ }
override fun reload(data: Map<ResourceLocation, MovesetBuilder>) {
movesetBuilders.clear()
data.forEach { (id, value) -> value.id = id }
movesetBuilders.putAll(data)
observable.emit(this)
}
}
@@ -1,47 +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
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.npc.PartyComposition
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
object CobblemonPartyCompositions : JsonDataRegistry<PartyComposition> {
override val id: ResourceLocation = cobblemonResource("party_compositions")
override val type = PackType.SERVER_DATA
override val typeToken: TypeToken<PartyComposition> = TypeToken.get(PartyComposition::class.java)
override val resourcePath: String = "party_compositions"
override val observable = SimpleObservable<CobblemonPartyCompositions>()
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.setPrettyPrinting()
.create()
val partyCompositions = mutableMapOf<ResourceLocation, PartyComposition>()
override fun sync(player: ServerPlayer) {
// probably worth syncing which exist, yeah. the deeper details probably not. I'll get to this eventually.
}
override fun reload(data: Map<ResourceLocation, PartyComposition>) {
data.entries.forEach { it.value.id = it.key }
partyCompositions.clear()
partyCompositions.putAll(data)
observable.emit(this)
Cobblemon.LOGGER.info("Loaded ${data.size} party compositions.")
}
}
@@ -1,60 +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
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.api.npc.PartyPool
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.util.ScriptableIntRange
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.IntRangeAdapter
import com.cobblemon.mod.common.util.adapters.MovesetBuilderReferenceAdapter
import com.cobblemon.mod.common.util.adapters.PokemonPropertiesAdapter
import com.cobblemon.mod.common.util.adapters.ScriptableIntRangeAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
object CobblemonPartyPools : JsonDataRegistry<PartyPool> {
override val id: ResourceLocation = cobblemonResource("party_pools")
override val type = PackType.SERVER_DATA
override val typeToken: TypeToken<PartyPool> = TypeToken.get(PartyPool::class.java)
override val resourcePath: String = "party_pools"
override val observable = SimpleObservable<CobblemonPartyPools>()
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(PokemonProperties::class.java, PokemonPropertiesAdapter(saveLong = false))
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
.registerTypeAdapter(ScriptableIntRange::class.java, ScriptableIntRangeAdapter)
.registerTypeAdapter(MovesetBuilder::class.java, MovesetBuilderReferenceAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.setPrettyPrinting()
.create()
val partyPools = mutableMapOf<ResourceLocation, PartyPool>()
override fun sync(player: ServerPlayer) {
// probably worth syncing. Knowing the details might help exploit the server? lot of effort for little though.
}
override fun reload(data: Map<ResourceLocation, PartyPool>) {
data.entries.forEach { it.value.id = it.key }
partyPools.clear()
partyPools.putAll(data)
observable.emit(this)
}
}
@@ -9,15 +9,14 @@
package com.cobblemon.mod.common
import net.minecraft.client.RecipeBookCategories
import net.minecraft.world.inventory.RecipeBookType
enum class CobblemonRecipeCategories {
COOKING_POT_SEARCH("COBBLEMON_COOKING_POT_SEARCH"),
COOKING_POT_FOODS("COBBLEMON_COOKING_POT_FOODS"),
COOKING_POT_MEDICINES("COBBLEMON_COOKING_POT_MEDICINES"),
COOKING_POT_COMPLEX_DISHES("COBBLEMON_COOKING_POT_COMPLEX_DISHES"),
COOKING_POT_MISC("COBBLEMON_COOKING_POT_MISC");
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
COOKING_POT_FOODS("COOKING_POT_FOODS"),
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
COOKING_POT_COMPLEX_DISHES("COOKING_POT_COMPLEX_DISHES"),
COOKING_POT_MISC("COOKING_POT_MISC");
companion object {
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
@@ -36,9 +35,6 @@ enum class CobblemonRecipeCategories {
fun toVanillaCategory(): RecipeBookCategories {
return RecipeBookCategories.valueOf(this.id)
}
}
object CobblemonRecipeBookTypes {
const val COOKING_POT_NAME = "COBBLEMON_COOKING_POT"
val COOKING_POT: RecipeBookType = RecipeBookType.valueOf(COOKING_POT_NAME)
}
@@ -1,44 +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.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.DefendOwnerTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class DefendOwnerTaskConfig : SingleTaskConfig {
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): List<MoLangConfigVariable> {
return emptyList()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
behaviourConfigurationContext.addMemories(
MemoryModuleType.ATTACK_TARGET,
CobblemonMemories.NEAREST_VISIBLE_ATTACKER,
)
return WrapperLivingEntityTask(
DefendOwnerTask.create(),
PokemonEntity::class.java
)
}
}
@@ -109,7 +109,7 @@ class PollinateFlowerTaskConfig : SingleTaskConfig {
}
override fun stop(level: ServerLevel, entity: LivingEntity, gameTime: Long) {
hoverPos = null
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
}
@@ -105,7 +105,6 @@ interface TaskConfig {
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
cobblemonResource("manage_flight_in_battle") to ManageFlightInBattleTaskConfig::class.java,
cobblemonResource("attack_hostile_mobs") to AttackHostileMobsTaskConfig::class.java,
cobblemonResource("defend_owner") to DefendOwnerTaskConfig::class.java,
cobblemonResource("move_to_sweet_berry_bush") to MoveToSweetBerryBushTaskConfig::class.java,
cobblemonResource("stop_moving_to_sweet_berry_bush") to StopTryingToReachSweetBerryBushTaskConfig::class.java,
cobblemonResource("harvest_sweet_berry_bush") to HarvestSweetBerryBushTaskConfig::class.java,
@@ -64,29 +64,21 @@ fun getColourMixFromColors(colors: List<Int>): Int? {
if (colors.isEmpty()) return null
if (colors.size == 1) return colors[0]
val firstWeight = 0.7f
val otherWeightTotal = 1f - firstWeight
val otherWeight = otherWeightTotal / (colors.size - 1)
var alphaSum = 0f
var redSum = 0f
var greenSum = 0f
var blueSum = 0f
for (i in colors.indices) {
val weight = if (i == 0) firstWeight else otherWeight
val color = colors[i]
alphaSum += FastColor.ARGB32.alpha(color) * weight
redSum += FastColor.ARGB32.red(color) * weight
greenSum += FastColor.ARGB32.green(color) * weight
blueSum += FastColor.ARGB32.blue(color) * weight
var alphaSum = 0
var redSum = 0
var greenSum = 0
var blueSum = 0
for (color in colors) {
alphaSum += FastColor.ARGB32.alpha(color)
redSum += FastColor.ARGB32.red(color)
greenSum += FastColor.ARGB32.green(color)
blueSum += FastColor.ARGB32.blue(color)
}
return FastColor.ARGB32.color(
alphaSum.toInt(),
redSum.toInt(),
greenSum.toInt(),
blueSum.toInt()
)
val alpha = alphaSum / colors.size
val red = redSum / colors.size
val green = greenSum / colors.size
val blue = blueSum / colors.size
return FastColor.ARGB32.color(alpha, red, green, blue)
}
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.repository.Varyi
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.toHex
import com.mojang.blaze3d.platform.GlStateManager
import com.mojang.blaze3d.platform.GLX
import com.mojang.blaze3d.platform.Lighting
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.BufferUploader
@@ -37,6 +38,8 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.util.FormattedCharSequence
import org.joml.Matrix4f
import org.joml.Vector3f
import org.lwjgl.opengl.GL30
import java.nio.ByteBuffer
@JvmOverloads
fun blitk(
@@ -367,3 +370,28 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
BufferUploader.drawWithShader(buffer.buildOrThrow())
}
fun getPixelRGB(x: Int, y: Int): Triple<Int, Int, Int> {
val window = Minecraft.getInstance().window
val scale = window.guiScale
val buffer = ByteBuffer.allocateDirect(4)
// Check if OpenGL context is present
if (!GLX.getOpenGLVersionString().equals("NO CONTEXT")) {
RenderSystem.readPixels(
(x * scale).toInt(),
(window.height - y * scale - scale).toInt(),
1,
1,
GL30.GL_RGBA,
GL30.GL_UNSIGNED_BYTE,
buffer
)
}
return Triple(
buffer[0].toInt() and 0xFF,
buffer[1].toInt() and 0xFF,
buffer[2].toInt() and 0xFF
)
}
@@ -1824,7 +1824,8 @@ object MoLangFunctions {
return@put DoubleValue(if (pokemon.addRideBoost(stat, value)) 1.0 else 0.0)
}
map.put("initialize_moveset") { params ->
pokemon.initializeMovesetFromDefault()
val preferLatest = params.getBooleanOrNull(0) ?: true
pokemon.initializeMoveset(preferLatest)
return@put DoubleValue.ONE
}
map.put("validate_moveset") { params ->
@@ -1,57 +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.api.moves
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.resources.ResourceLocation
/**
* This is all you need tbh. A moveset builder that picks moves from up to 4 slots of move selectors.
*
* @author Hiroku
* @since December 5th, 2025
*/
class DefaultMovesetBuilder : MovesetBuilder {
companion object {
val TYPE = cobblemonResource("default")
}
override val type: ResourceLocation = TYPE
override var id: ResourceLocation = cobblemonResource("temp") // replaced on load.
val slot1: List<MoveSelector> = listOf()
val slot2: List<MoveSelector> = listOf()
val slot3: List<MoveSelector> = listOf()
val slot4: List<MoveSelector> = listOf()
override fun build(form: FormData, level: Int): MoveSet {
val chosenMoves = mutableSetOf<MoveTemplate>()
tryAddMoveFromSlot(form, level, slot1, chosenMoves)
tryAddMoveFromSlot(form, level, slot2, chosenMoves)
tryAddMoveFromSlot(form, level, slot3, chosenMoves)
tryAddMoveFromSlot(form, level, slot4, chosenMoves)
if (chosenMoves.isEmpty()) {
chosenMoves.add(Moves.getExceptional())
}
val moveset = MoveSet()
chosenMoves.map(MoveTemplate::create).forEach(moveset::add)
return moveset
}
fun tryAddMoveFromSlot(form: FormData, level: Int, selectors: List<MoveSelector>, chosenMoves: MutableSet<MoveTemplate>) {
for (selector in selectors) {
val move = selector(form, form.moves, level, chosenMoves)
if (move != null) {
chosenMoves.add(move)
return
}
}
}
}
@@ -1,148 +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.api.moves
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
import com.cobblemon.mod.common.api.pokemon.moves.Learnset
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.util.weightedSelection
/**
* A function that selects a move from a given [Learnset] for a particular [FormData] at a certain level,
* taking into account any moves that have already been chosen for the moveset.
*
* @author Hiroku
* @since December 5th, 2025
*/
fun interface MoveSelector {
operator fun invoke(form: FormData, learnset: Learnset, level: Int, chosenMoves: Set<MoveTemplate>): MoveTemplate?
companion object {
val NONE = MoveSelector { _, _, _, _ -> null }
val LAST_LEVELUP = MoveSelector { form, learnset, level, chosenMoves ->
val levels = learnset.levelUpMoves.keys.filter { it <= level }.sortedDescending()
levels.forEach {
val moves = (learnset.levelUpMoves[it] ?: return@forEach) - chosenMoves
if (moves.isNotEmpty()) {
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
}
return@MoveSelector null
}
val LAST_OFFENSIVE = MoveSelector { form, learnset, level, chosenMoves ->
val levels = learnset.levelUpMoves.keys.filter { it <= level }.sortedDescending()
levels.forEach {
val moves = (learnset.levelUpMoves[it]?.filter { it.damageCategory != DamageCategories.STATUS } ?: return@forEach) - chosenMoves
if (moves.isNotEmpty()) {
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
}
return@MoveSelector null
}
val LAST_SUITABLE_OFFENSIVE = MoveSelector { form, learnset, level, chosenMoves ->
val levels = learnset.levelUpMoves.keys.filter { it <= level }.sortedDescending()
val suitableCategories = if (form.baseStats[Stats.ATTACK]!! > form.baseStats[Stats.SPECIAL_ATTACK]!!) {
setOf(DamageCategories.PHYSICAL)
} else if (form.baseStats[Stats.SPECIAL_ATTACK]!! > form.baseStats[Stats.ATTACK]!!) {
setOf(DamageCategories.SPECIAL)
} else {
setOf(DamageCategories.PHYSICAL, DamageCategories.SPECIAL)
}
levels.forEach {
val moves = (learnset.levelUpMoves[it]?.filter { it.damageCategory in suitableCategories } ?: return@forEach) - chosenMoves
if (moves.isNotEmpty()) {
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
}
return@MoveSelector null
}
val LAST_STATUS = MoveSelector { form, learnset, level, chosenMoves ->
val levels = learnset.levelUpMoves.keys.filter { it <= level }.sortedDescending()
levels.forEach {
val moves = (learnset.levelUpMoves[it]?.filter { it.damageCategory == DamageCategories.STATUS } ?: return@forEach) - chosenMoves
if (moves.isNotEmpty()) {
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
}
return@MoveSelector null
}
val STAB = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val stabMoves = moves.filter { it.elementalType in form.types && it.damageCategory != DamageCategories.STATUS }
return@MoveSelector stabMoves.weightedSelection { it.getSelectionWeight(form) }
}
val STAB_PHYSICAL = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val stabMoves = moves.filter { it.elementalType in form.types && it.damageCategory == DamageCategories.PHYSICAL }
return@MoveSelector stabMoves.weightedSelection { it.getSelectionWeight(form) }
}
val STAB_SPECIAL = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val stabMoves = moves.filter { it.elementalType in form.types && it.damageCategory == DamageCategories.SPECIAL }
return@MoveSelector stabMoves.weightedSelection { it.getSelectionWeight(form) }
}
val PHYSICAL = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val physicalMoves = moves.filter { it.damageCategory == DamageCategories.PHYSICAL }
return@MoveSelector physicalMoves.weightedSelection { it.getSelectionWeight(form) }
}
val SPECIAL = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val specialMoves = moves.filter { it.damageCategory == DamageCategories.SPECIAL }
return@MoveSelector specialMoves.weightedSelection { it.getSelectionWeight(form) }
}
val OFFENSIVE = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val offensiveMoves = moves.filter { it.damageCategory != DamageCategories.STATUS }
return@MoveSelector offensiveMoves.weightedSelection { it.getSelectionWeight(form) }
}
val RANDOM_LEVELUP = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
val STATUS = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.getLevelUpMovesUpTo(level) - chosenMoves
val statusMoves = moves.filter { it.damageCategory == DamageCategories.STATUS }
return@MoveSelector statusMoves.weightedSelection { it.getSelectionWeight(form) }
}
val TM = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.tmMoves - chosenMoves - learnset.getLevelUpMovesUpTo(level)
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
val STAB_TM = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.tmMoves - chosenMoves - learnset.getLevelUpMovesUpTo(level)
val stabMoves = moves.filter { it.elementalType in form.types }
return@MoveSelector stabMoves.weightedSelection { it.getSelectionWeight(form) }
}
val EGG = MoveSelector { form, learnset, level, chosenMoves ->
val moves = learnset.eggMoves - chosenMoves - learnset.getLevelUpMovesUpTo(level)
return@MoveSelector moves.weightedSelection { it.getSelectionWeight(form) }
}
val selectors = mutableMapOf(
"none" to NONE,
"last_levelup" to LAST_LEVELUP,
"last_offensive" to LAST_OFFENSIVE,
"last_suitable_offensive" to LAST_SUITABLE_OFFENSIVE,
"last_status" to LAST_STATUS,
"levelup" to RANDOM_LEVELUP,
"stab" to STAB,
"stab_physical" to STAB_PHYSICAL,
"stab_special" to STAB_SPECIAL,
"physical" to PHYSICAL,
"special" to SPECIAL,
"offensive" to OFFENSIVE,
"status" to STATUS,
"tm" to TM,
"stab_tm" to STAB_TM,
"egg" to EGG
)
}
}
@@ -12,12 +12,12 @@ import com.bedrockk.molang.runtime.struct.MoStruct
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
import com.cobblemon.mod.common.api.moves.categories.DamageCategory
import com.cobblemon.mod.common.api.types.ElementalType
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.battles.MoveTarget
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.util.codec.CodecUtils
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.lang
@@ -53,8 +53,7 @@ open class MoveTemplate(
val pp: Int,
val priority: Int,
val critRatio: Double,
val effectChances: Array<Double>,
val weight: Float
val effectChances: Array<Double>
) {
val struct: MoStruct by lazy {
QueryStruct(hashMapOf())
@@ -67,9 +66,9 @@ open class MoveTemplate(
.addFunction("pp") { DoubleValue(pp) }
.addFunction("priority") { DoubleValue(priority) }
.addFunction("crit_ratio") { DoubleValue(critRatio) }
.addFunction("weight") { DoubleValue(weight.toDouble()) }
}
val displayName: MutableComponent
get() = lang("move.$name")
val description: MutableComponent
@@ -87,8 +86,7 @@ open class MoveTemplate(
pp = 5,
priority = 0,
critRatio = 0.0,
effectChances = emptyArray(),
weight = 0F,
effectChances = emptyArray()
)
companion object {
@@ -159,12 +157,4 @@ open class MoveTemplate(
}
return this.elementalType
}
fun getSelectionWeight(form: FormData): Float {
return if (this in form.signatureMoves) {
weight * MovesetBuilder.signatureMoveWeightMultiplier
} else {
weight
}
}
}
@@ -10,15 +10,15 @@ package com.cobblemon.mod.common.api.moves
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.data.DataRegistry
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.battles.MoveTarget
import com.cobblemon.mod.common.battles.runner.ShowdownService
import com.cobblemon.mod.common.net.messages.client.data.MovesRegistrySyncPacket
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.fromJson
import com.google.gson.GsonBuilder
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import net.minecraft.resources.ResourceLocation
@@ -46,14 +46,6 @@ object Moves : DataRegistry {
this.idMapping.clear()
this.moveScripts.clear()
val weights = mutableMapOf<String, Number>()
manager.getResourceStack(cobblemonResource("move_weights.json")).forEach {
it.open().use {
val map = GsonBuilder().create().fromJson<Map<String, Number>>(it.reader())
weights.putAll(map)
}
}
ShowdownService.service.resetRegistryData("move")
manager.listResources("moves") { it.path.endsWith(".js") }.forEach { (identifier, resource) ->
resource.open().use { stream ->
@@ -83,7 +75,6 @@ object Moves : DataRegistry {
val priority = jsMove.get("priority").asInt
val critRatio = jsMove.get("critRatio")?.asDouble ?: 1.0
val effectChances = arrayListOf<Double>()
val weight = weights[id]?.toFloat() ?: 50F
val secondariesMember = jsMove.get("secondaries")
val secondaryMember = jsMove.get("secondary")
if (secondariesMember != null && secondariesMember is JsonArray) {
@@ -101,20 +92,7 @@ object Moves : DataRegistry {
effectChances += secondaryMember.get("chance").asDouble
}
}
val move = MoveTemplate(
name = id,
num = num,
elementalType = elementalType,
damageCategory = damageCategory,
power = power,
target = target,
accuracy = accuracy,
pp = pp,
priority = priority,
critRatio = critRatio,
effectChances = effectChances.toTypedArray(),
weight = weight
)
val move = MoveTemplate(id, num, elementalType, damageCategory, power, target, accuracy, pp, priority, critRatio, effectChances.toTypedArray())
this.register(move)
} catch (e: Exception) {
Cobblemon.LOGGER.error("Caught exception trying to resolve the move '{}'", id, e)
@@ -135,7 +113,7 @@ object Moves : DataRegistry {
@JvmStatic
fun getByNameOrDummy(name: String) = allMoves[name.lowercase()] ?: MoveTemplate.dummy(name.lowercase())
@JvmStatic
fun getExceptional() = getByName("tackle") ?: allMoves.values.first()
fun getExceptional() = getByName("tackle") ?: allMoves.values.random()
@JvmStatic
fun count() = allMoves.size
@JvmStatic
@@ -151,4 +129,5 @@ object Moves : DataRegistry {
this.allMoves[move.name] = move
this.idMapping[move.num] = move
}
}
@@ -1,38 +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.api.moves
import com.cobblemon.mod.common.pokemon.FormData
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.resources.ResourceLocation
/**
* Builders a moveset for a particular [FormData] and level. Probably only really need [DefaultMovesetBuilder] though.
*
* @author Hiroku
* @since December 5th, 2025
*/
interface MovesetBuilder {
/** The ID of this builder. It's autofilled from the registry loader. */
var id: ResourceLocation
/** The subtype designation for this moveset builder. Generally unused once read from JSON. */
val type: ResourceLocation
/** Builds a brand new moveset for the [form] and [level]. */
fun build(form: FormData, level: Int): MoveSet
companion object {
/** Weight multiplier for moves that are in the form's signatureMoves list. Makes them way more likely to be chosen. */
var signatureMoveWeightMultiplier = 5F
/** Subtypes of MovesetBuilder. I personally doubt you'll need any other subtypes, but hey. */
val movesetBuilderTypes = mutableMapOf<ResourceLocation, Class<out MovesetBuilder>>(
cobblemonResource("default") to DefaultMovesetBuilder::class.java
)
}
}
@@ -8,14 +8,12 @@
package com.cobblemon.mod.common.api.npc
import com.cobblemon.mod.common.api.npc.partyproviders.ComposedPoolPartyProvider
import com.cobblemon.mod.common.api.npc.partyproviders.PoolPartyProvider
import com.cobblemon.mod.common.api.npc.partyproviders.ScriptPartyProvider
import com.cobblemon.mod.common.api.npc.partyproviders.SimplePartyProvider
import com.cobblemon.mod.common.api.storage.party.NPCPartyStore
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.google.gson.JsonElement
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
/**
@@ -27,15 +25,14 @@ import net.minecraft.server.level.ServerPlayer
*/
interface NPCPartyProvider {
companion object {
val types = mutableMapOf(
SimplePartyProvider.TYPE to ::SimplePartyProvider,
PoolPartyProvider.TYPE to ::PoolPartyProvider,
ScriptPartyProvider.TYPE to ::ScriptPartyProvider,
ComposedPoolPartyProvider.TYPE to ::ComposedPoolPartyProvider
val types = mutableMapOf<String, (String) -> NPCPartyProvider>(
SimplePartyProvider.TYPE to { SimplePartyProvider() },
PoolPartyProvider.TYPE to { PoolPartyProvider() },
ScriptPartyProvider.TYPE to { ScriptPartyProvider() }
)
}
val type: ResourceLocation
val type: String
val isStatic: Boolean
fun provide(npc: NPCEntity, level: Int, players: List<ServerPlayer> = emptyList()): NPCPartyStore
// Why did I opt for manual JSON loading??? I must have had a reason but I can't remember. Maybe for S2C? Use a codec doofus
@@ -1,68 +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.api.npc
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import kotlin.random.Random
/**
* A kind of definition for how to compose a party of Pokémon given a [PartyPool].
*
* @author Hiroku
* @since December 7th, 2025
*/
class PartyComposition {
var id = cobblemonResource("dummy_composition")
// val displayName = "cobblemon.party_composition.$id" // dunno if i will use this yet
val scrambleOrder: Boolean = false
val slot1 = listOf<String>()
val slot2 = listOf<String>()
val slot3 = listOf<String>()
val slot4 = listOf<String>()
val slot5 = listOf<String>()
val slot6 = listOf<String>()
fun compose(pool: PartyPool, level: Int, aspects: Set<String>, desiredPokemonCount: Int, runtime: MoLangRuntime, random: Random = Random.Default): List<Pokemon> {
val chosenEntries = mutableListOf<PartyPool.PoolEntry>()
val availableEntries = pool.entries.filter { level in it.npcLevels.resolve(runtime) && (it.npcAspects.isEmpty() || it.npcAspects.all(aspects::contains)) }
for (labelSet in listOf(slot1, slot2, slot3, slot4, slot5, slot6)) {
pool.tryChoosingEntry(labelSet, runtime, random, availableEntries, chosenEntries)
if (chosenEntries.size >= desiredPokemonCount) {
break
}
}
val finalEntries = if (scrambleOrder) {
chosenEntries.shuffled(random)
} else {
chosenEntries
}
val pokemon = finalEntries.map { entry ->
val levelVariation = entry.levelVariation.resolve(runtime)
val lvlVariation = if (levelVariation.first == levelVariation.last) {
levelVariation.first
} else {
levelVariation.random(random)
}
val finalLevel = level + lvlVariation
val properties = entry.pokemon.copy()
properties.level = properties.level ?: finalLevel
val pokemon = properties.create()
entry.movesetBuilders.randomOrNull()?.let(pokemon::initializeMovesetFrom)
pokemon
}
return pokemon
}
}
@@ -1,77 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.npc
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.util.ScriptableIntRange
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.toProperties
import com.cobblemon.mod.common.util.weightedSelection
import kotlin.random.Random
/**
* A pool of Pokémon to choose from, typically for generating a party for an NPC. The entries
* of the pool work on a weight and label system which is used as part of a [PartyComposition].
*
* @author Hiroku
* @since December 7th, 2025
*/
class PartyPool {
var id = cobblemonResource("dummy")
val displayName = "cobblemon.party_pool.$id"
val entries = mutableListOf<PoolEntry>()
class PoolEntry {
val pokemon: PokemonProperties = "pikachu".toProperties()
val labels: List<String> = emptyList()
val npcAspects: List<String> = emptyList()
val required: List<String> = emptyList()
val incompatible: List<String> = emptyList()
val maxSelectableTimes: ExpressionLike = "6".asExpressionLike()
val levelVariation: ScriptableIntRange = ScriptableIntRange(0, 0)
val npcLevels: ScriptableIntRange = ScriptableIntRange(1, 100)
val movesetBuilders: List<MovesetBuilder> = emptyList()
val weight: ExpressionLike = "50".asExpressionLike()
}
/**
* Goes through each of the labels in order, trying to find a valid choice. Once it finds one, it skips the later
* labels and adds the value to [chosenEntries] and returns. If none of the labels could find a valid entry, nothing is added.
*/
fun tryChoosingEntry(
labels: List<String>,
runtime: MoLangRuntime,
random: Random,
availableEntries: List<PoolEntry>,
chosenEntries: MutableList<PoolEntry>,
) {
for (label in labels) {
val entries = availableEntries
.filter { label in it.labels || label.lowercase() == "any" }
.filter { entry ->
// Check required labels
entry.required.all { it in labels } &&
// Check excluded labels
entry.incompatible.none { it in labels } &&
// Check max selectable times
chosenEntries.count { it == entry } < entry.maxSelectableTimes.resolveFloat(runtime)
}
if (entries.isNotEmpty()) {
val selectedEntry = entries.weightedSelection(random) { it.weight.resolveFloat(runtime) } ?: return
chosenEntries.add(selectedEntry)
return
}
}
}
}
@@ -1,94 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.npc.partyproviders
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.CobblemonPartyCompositions
import com.cobblemon.mod.common.CobblemonPartyPools
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.npc.NPCPartyProvider
import com.cobblemon.mod.common.api.npc.PartyComposition
import com.cobblemon.mod.common.api.npc.PartyPool
import com.cobblemon.mod.common.api.storage.party.NPCPartyStore
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.util.asArrayValue
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.withQueryValue
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import kotlin.random.Random
import kotlin.ranges.random
import net.minecraft.server.level.ServerPlayer
/**
* An [NPCPartyProvider] which uses a [PartyComposition] and [PartyPool] to generate a party.
*
* There are controls for minimum and maximum Pokémon count, as well as whether to use a fixed random seed for the NPC.
*
* @author Hiroku
* @since December 8th, 2025
*/
class ComposedPoolPartyProvider : NPCPartyProvider {
companion object {
val TYPE = cobblemonResource("composed_pool")
}
override val type = TYPE
override var isStatic: Boolean = true
var useFixedRandom: Boolean = false
var minPokemon: Expression = "1".asExpression()
var maxPokemon: Expression = "6".asExpression()
lateinit var pool: PartyPool
lateinit var composition: PartyComposition
override fun loadFromJSON(json: JsonElement) {
json as JsonObject
isStatic = json.getAsJsonPrimitive("isStatic")?.asBoolean ?: true
useFixedRandom = json.getAsJsonPrimitive("useFixedRandom")?.asBoolean ?: false
pool = CobblemonPartyPools.partyPools[json.get("pool").asString.asIdentifierDefaultingNamespace()]
?: throw IllegalArgumentException("Unknown PartyPool id: ${json.get("pool").asString}")
composition = CobblemonPartyCompositions.partyCompositions[json.get("composition").asString.asIdentifierDefaultingNamespace()]
?: throw IllegalArgumentException("Unknown PartyComposition id: ${json.get("composition").asString}")
minPokemon = json.getAsJsonPrimitive("minPokemon").asString?.asExpression() ?: "1".asExpression()
maxPokemon = json.getAsJsonPrimitive("maxPokemon").asString?.asExpression() ?: "6".asExpression()
}
override fun provide(npc: NPCEntity, level: Int, players: List<ServerPlayer>): NPCPartyStore {
val runtime = MoLangRuntime().setup().withQueryValue("npc", npc.struct)
val random = if (useFixedRandom) Random(npc.uuid.hashCode()) else Random.Default
runtime.withQueryValue("level", DoubleValue(level))
runtime.withQueryValue("players", players.asArrayValue { it.asMoLangValue() })
if (players.size == 1) {
// This is for the convenience, most cases will be pvn one player
runtime.withQueryValue("player", players.first().asMoLangValue())
}
val minPokemon = runtime.resolveInt(this.minPokemon)
val maxPokemon = runtime.resolveInt(this.maxPokemon)
val desiredPokemonCount = (minPokemon..maxPokemon).random(random)
val pokemonList = composition.compose(
pool = pool,
level = level,
aspects = npc.aspects,
desiredPokemonCount = desiredPokemonCount,
runtime = runtime,
random = random
)
val partyStore = NPCPartyStore(npc)
pokemonList.forEach(partyStore::add)
return partyStore
}
}
@@ -48,7 +48,7 @@ import kotlin.random.Random
*/
class PoolPartyProvider : NPCPartyProvider {
companion object {
val TYPE = cobblemonResource("pool")
const val TYPE = "pool"
}
@Transient
@@ -150,10 +150,10 @@ class PoolPartyProvider : NPCPartyProvider {
val instance = selected.pokemon.copy().also { it.level = it.level ?: dictatedLevel ?: randomLevel }.create()
party.add(instance)
}
if (party.none()) {
LOGGER.error("$npc had no Pokémon produced by their party provider")
LOGGER.error("${npc} has no Pokemon on Party")
}
}
override fun provide(npc: NPCEntity, level: Int, players: List<ServerPlayer>): NPCPartyStore {
@@ -28,7 +28,7 @@ import net.minecraft.server.level.ServerPlayer
class ScriptPartyProvider : NPCPartyProvider {
companion object {
val TYPE = cobblemonResource("script")
const val TYPE = "script"
}
override val type = TYPE
@@ -16,7 +16,6 @@ import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.storage.party.NPCPartyStore
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.util.asArrayValue
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.getBooleanOrNull
import com.cobblemon.mod.common.util.toProperties
import com.google.gson.JsonElement
@@ -30,7 +29,7 @@ import net.minecraft.server.level.ServerPlayer
*/
class SimplePartyProvider : NPCPartyProvider {
companion object {
val TYPE = cobblemonResource("simple")
const val TYPE = "simple"
}
@Transient
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.pokemon
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.Cobblemon.config
import com.cobblemon.mod.common.CobblemonMovesetBuilders
import com.cobblemon.mod.common.api.abilities.Abilities
import com.cobblemon.mod.common.api.abilities.Ability
import com.cobblemon.mod.common.api.events.CobblemonEvents
@@ -149,13 +148,6 @@ open class PokemonProperties {
props.originalTrainerType = OriginalTrainerType.entries.toList().parsePropertyOfCollection(keyPairs, listOf("originaltrainertype", "ottype"), labelsOptional = true) { it.name.lowercase() }
props.originalTrainer = parsePlayerProperty(keyPairs, listOf("originaltrainer", "ot"))
props.moves = parseString(keyPairs, listOf("moves"))?.split(",")
props.movesetBuilders = parseString(keyPairs, listOf("moveset_builders", "movesetbuilders", "moveset_builder", "movesetbuilder"))?.split(",")?.mapNotNull {
try {
it.asIdentifierDefaultingNamespace()
} catch (_: ResourceLocationException) {
null
}
}
props.heldItem = parseString(keyPairs, listOf("helditem", "held_item"))
props.minPerfectIVs = parseIntProperty(keyPairs, listOf("min_perfect_ivs"))?.coerceIn(0, Stats.PERMANENT.size)
props.scaleModifier = parseFloatProperty(keyPairs, listOf("scale_modifier"))
@@ -364,7 +356,6 @@ open class PokemonProperties {
var originalTrainerType: OriginalTrainerType? = null
var originalTrainer: String? = null // Original Trainer by Username or UUID
var moves: List<String>? = null
var movesetBuilders: List<ResourceLocation>? = null
var heldItem: String? = null
var cosmeticItem: String? = null
var scaleModifier: Float? = null
@@ -471,7 +462,7 @@ open class PokemonProperties {
}
moves?.let { moves ->
if (pokemon.moveSet.getMoves().isEmpty()) {
pokemon.initializeMovesetFromDefault()
pokemon.initializeMoveset(preferLatest = true)
}
val moveTemplates = moves.mapNotNull(Moves::getByName).shuffled()
val replaceableIndices = (0..3).filterNot { pokemon.moveSet[it]?.template?.let(moveTemplates::contains) == true }.shuffled()
@@ -484,13 +475,6 @@ open class PokemonProperties {
pokemon.moveSet.update()
}
}
movesetBuilders?.let { movesetBuilders ->
val builders = movesetBuilders.mapNotNull { CobblemonMovesetBuilders.movesetBuilders[it] }
if (builders.isNotEmpty()) {
val movesetBuilder = builders.random()
pokemon.initializeMovesetFrom(movesetBuilder)
}
}
heldItem?.let { itemKey ->
val server = server() ?: return@let
val parser = ItemParser(server.registryAccess())
@@ -694,7 +678,6 @@ open class PokemonProperties {
originalTrainerType?.let { nbt.putInt(DataKeys.POKEMON_ORIGINAL_TRAINER_TYPE, it.ordinal) }
originalTrainer?.let { nbt.putString(DataKeys.POKEMON_ORIGINAL_TRAINER, it) }
moves?.let { nbt.putString(DataKeys.POKEMON_PROPERTIES_MOVES, it.joinToString(separator = ",")) }
movesetBuilders?.let { nbt.putString(DataKeys.POKEMON_PROPERTIES_MOVESET_BUILDERS, it.joinToString(separator = ",") { source -> source.toString() }) }
heldItem?.let {nbt.putString(DataKeys.POKEMON_PROPERTIES_HELDITEM, it)}
scaleModifier?.let { nbt.putFloat(DataKeys.POKEMON_SCALE_MODIFIER, it) }
val custom = ListTag()
@@ -729,7 +712,6 @@ open class PokemonProperties {
originalTrainerType = if (tag.contains(DataKeys.POKEMON_ORIGINAL_TRAINER_TYPE)) OriginalTrainerType.valueOf(tag.getString(DataKeys.POKEMON_ORIGINAL_TRAINER_TYPE)) else null
originalTrainer = if (tag.contains(DataKeys.POKEMON_ORIGINAL_TRAINER)) tag.getString(DataKeys.POKEMON_ORIGINAL_TRAINER) else null
moves = if (tag.contains(DataKeys.POKEMON_PROPERTIES_MOVES)) tag.getString(DataKeys.POKEMON_PROPERTIES_MOVES).split(",") else null
movesetBuilders = if (tag.contains(DataKeys.POKEMON_PROPERTIES_MOVESET_BUILDERS)) tag.getString(DataKeys.POKEMON_PROPERTIES_MOVESET_BUILDERS).split(",").map { it.asIdentifierDefaultingNamespace() } else null
heldItem = if (tag.contains(DataKeys.POKEMON_PROPERTIES_HELDITEM)) tag.getString(DataKeys.POKEMON_PROPERTIES_HELDITEM) else null
scaleModifier = if (tag.contains(DataKeys.POKEMON_SCALE_MODIFIER)) tag.getFloat(DataKeys.POKEMON_SCALE_MODIFIER) else null
val custom = tag.getList(DataKeys.POKEMON_PROPERTIES_CUSTOM, Tag.TAG_STRING.toInt())
@@ -765,7 +747,6 @@ open class PokemonProperties {
originalTrainerType?.let { json.addProperty(DataKeys.POKEMON_ORIGINAL_TRAINER_TYPE, it.name) }
originalTrainer?.let { json.addProperty(DataKeys.POKEMON_ORIGINAL_TRAINER, it) }
moves?.let { json.addProperty(DataKeys.POKEMON_PROPERTIES_MOVES, it.joinToString(separator = ",")) }
movesetBuilders?.let { json.addProperty(DataKeys.POKEMON_PROPERTIES_MOVESET_BUILDERS, it.joinToString(separator = ",") { source -> source.toString() }) }
heldItem?.let {json.addProperty(DataKeys.POKEMON_PROPERTIES_HELDITEM, it)}
scaleModifier?.let { json.addProperty(DataKeys.POKEMON_SCALE_MODIFIER, it) }
val custom = JsonArray()
@@ -800,7 +781,6 @@ open class PokemonProperties {
originalTrainerType = json.get(DataKeys.POKEMON_ORIGINAL_TRAINER_TYPE)?.asString?.let { OriginalTrainerType.valueOf(it) }
originalTrainer = json.get(DataKeys.POKEMON_ORIGINAL_TRAINER)?.asString
moves = json.get(DataKeys.POKEMON_PROPERTIES_MOVES)?.asString?.split(",")
movesetBuilders = json.get(DataKeys.POKEMON_PROPERTIES_MOVESET_BUILDERS)?.asString?.split(",")?.map { it.asIdentifierDefaultingNamespace() }
heldItem = json.get(DataKeys.POKEMON_PROPERTIES_HELDITEM)?.asString
scaleModifier = json.get(DataKeys.POKEMON_SCALE_MODIFIER)?.asFloat
val custom = json.get(DataKeys.POKEMON_PROPERTIES_CUSTOM)?.asJsonArray
@@ -840,7 +820,6 @@ open class PokemonProperties {
originalTrainer?.let { pieces.add("originaltrainer=$it") }
customProperties.forEach { pieces.add(it.asString()) }
moves?.let { pieces.add("moves=${it.joinToString(separator = ",")}") }
movesetBuilders?.let { pieces.add("movesetbuilders=${it.joinToString(separator = ",") { source -> source.toString() }}") }
heldItem?.let {pieces.add("helditem=$it")}
scaleModifier?.let { pieces.add("scale_modifier=$it") }
return pieces.joinToString(separator)
@@ -23,7 +23,6 @@ import com.cobblemon.mod.common.api.drop.ItemDropMethod
import com.cobblemon.mod.common.api.entity.EntityDimensionsAdapter
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.api.moves.adapters.MoveTemplateAdapter
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies.getByIdentifier
@@ -132,7 +131,6 @@ object PokemonSpecies : JsonDataRegistry<Species> {
.registerTypeAdapter(RidingBehaviourSettings::class.java, RidingBehaviourSettingsAdapter)
.registerTypeAdapter(RideSoundSettingsList::class.java, RideSoundSettingsListAdapter)
.registerTypeAdapter(ObtainableItemCondition::class.java, ObtainableItemConditionAdapter)
.registerTypeAdapter(MovesetBuilder::class.java, MovesetBuilderReferenceAdapter)
.disableHtmlEscaping()
.enableComplexMapKeySerialization()
.create()
@@ -322,7 +322,7 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
val pitchRot = handling * state.currMouseYForce.get()
// Roll
val rollRot = handling * state.currMouseXForce.get()
val rollRot = handling * 1.5 * state.currMouseXForce.get()
val mouseRotation = Vec3(0.0, pitchRot, rollRot)
@@ -114,10 +114,10 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
input: Vec3
) {
if (vehicle.level().isClientSide) {
handleSprinting(state, driver)
handleSprinting(state)
inAirCheck(state, vehicle)
tickStamina(settings, state, vehicle)
state.walking.set(state.rideVelocity.get().horizontalDistance() > 0.01 || driver.zza != 0.0f)
state.walking.set(state.rideVelocity.get().horizontalDistance() > 0.01)
}
}
@@ -139,24 +139,9 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
}
fun handleSprinting(
state: HorseState,
driver: Player
state: HorseState
) {
val sprintTimerTickLength = 7 // Emulate vanillas tick timer length
var hasDoubleTapped = false
// If you are not sprinting and you just pressed down and theres no
if (!state.forwardHeldLastTick.get() && Minecraft.getInstance().options.keyUp.isDown() && !state.sprinting.get() && state.sprintTickTimer.get() == 0) {
state.sprintTickTimer.set(sprintTimerTickLength)
} else if (!state.forwardHeldLastTick.get() && Minecraft.getInstance().options.keyUp.isDown() && state.sprintTickTimer.get() != 0) { // If has double tapped
hasDoubleTapped = true
}else if(!state.sprinting.get() && state.sprintTickTimer.get() > 0) {
state.sprintTickTimer.set(state.sprintTickTimer.get() - 1)
} else {
state.sprintTickTimer.set(0)
}
val tryingToSprint = (Minecraft.getInstance().options.keySprint.isDown() && Minecraft.getInstance().options.keyUp.isDown()) || hasDoubleTapped
val tryingToSprint = Minecraft.getInstance().options.keySprint.isDown() && Minecraft.getInstance().options.keyUp.isDown()
if (state.stamina.get() <= 0.0f || !Minecraft.getInstance().options.keyUp.isDown()) {
// If stamina runs out or the player is not holding forward then stop sprinting
@@ -171,9 +156,6 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
// If you are trying to sprint and the toggle allows it then start sprinting and disable toggle
state.sprinting.set(true)
}
// Take not of whether forward was held last tick
state.forwardHeldLastTick.set(Minecraft.getInstance().options.keyUp.isDown())
}
fun tickStamina(
@@ -245,7 +227,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
// Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot).coerceIn(-maxYawDiff,maxYawDiff)
val rotDiffNorm = rotDiff / maxYawDiff//(rotDiff / maxYawDiff).coerceIn(-0.2f, 0.2f)
val rotDiffNorm = rotDiff / maxYawDiff
// Take the square root so that the ride levels out quicker when at lower differences between entity
// y and driver y
@@ -258,7 +240,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
val walkSpeed = getWalkSpeed(vehicle)
val w = max(walkSpeed, vehicle.deltaMovement.horizontalDistance())
val invRelSpeed = (RidingBehaviour.scaleToRange(w, walkSpeed, topSpeed ) - 1.0f) * -1.0f
val turnRate = ((handling.toFloat() / 20.0f) * max(walkHandlingBoost * sqrt(abs(invRelSpeed)), 1.0)).toFloat()
val turnRate = ((handling.toFloat() / 20.0f) * max(walkHandlingBoost * invRelSpeed, 1.0)).toFloat()
// Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod
@@ -291,24 +273,30 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalHorse.speedExpr!!)
val walkSpeed = getWalkSpeed(vehicle)
val topSpeed = if(canSprint && state.sprinting.get()) rideTopSpeed else walkSpeed
val accelTime = if(state.sprinting.get()) (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHorse.accelerationExpr!!) * 20.0) else 0.5 * 20.0
val accel = topSpeed / accelTime
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHorse.accelerationExpr!!) * 20.0)
var activeInput = false
/******************************************************
* Gather the previous velocity and check for horizontal
* collisions
*****************************************************/
val dmSpeed = vehicle.deltaMovement.length()
val rvSpeed = state.rideVelocity.get().length()
var newVelocity = state.rideVelocity.get() //.normalize().scale(vehicle.deltaMovement.horizontalDistance())
/******************************************************
* Gather the previous velocity and check for horizontal
* collisions
*****************************************************/
// if (dmSpeed > rvSpeed) {
// // align the velocity vector to be in local vehicle space
// newVelocity = vehicle.deltaMovement
// val yawAligned = Matrix3f().rotateY(-vehicle.yRot.toRadians())
// newVelocity = (newVelocity.toVector3f().mul(yawAligned)).toVec3d()
// }
if (vehicle.horizontalCollision) {
var horizontalVec = Vec3(newVelocity.x, 0.0, newVelocity.z)
horizontalVec = horizontalVec.normalize().scale(min(horizontalVec.length(), 0.3))
newVelocity = Vec3(horizontalVec.x, newVelocity.y, horizontalVec.z)
newVelocity = newVelocity.normalize().scale(vehicle.deltaMovement.length())
}
/******************************************************
@@ -384,7 +372,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
state.jumpTicks.set(state.jumpTicks.get() + 1)
}
// Zero out lateral velocity possibly picked up from a controller transition
//Zero out lateral velocity possibly picked up from a controller transition
newVelocity = Vec3(0.0, newVelocity.y, newVelocity.z)
@@ -473,7 +461,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
vehicle: PokemonEntity,
driver: Player
): Float {
return if (state.sprinting.get()) 1.15f else 1.0f
return 1.0f
}
override fun useAngVelSmoothing(
@@ -532,14 +520,6 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
return true
}
override fun maxUpStep(
settings: HorseSettings,
state: HorseState,
vehicle: PokemonEntity
): Float? {
return if (state.inAir.get()) 0.0f else 1.2f
}
override fun getRideSounds(
settings: HorseSettings,
state: HorseState,
@@ -638,8 +618,6 @@ class HorseState : RidingBehaviourState() {
var sprintToggleable = ridingState(false, Side.CLIENT)
var inAir = ridingState(false, Side.CLIENT)
var jumpTicks = ridingState(0, Side.CLIENT)
var sprintTickTimer = ridingState(0, Side.CLIENT)
var forwardHeldLastTick = ridingState(false, Side.CLIENT)
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
@@ -648,8 +626,6 @@ class HorseState : RidingBehaviourState() {
buffer.writeBoolean(sprintToggleable.get())
buffer.writeBoolean(inAir.get())
buffer.writeInt(jumpTicks.get())
buffer.writeInt(sprintTickTimer.get())
buffer.writeBoolean(forwardHeldLastTick.get())
}
override fun decode(buffer: FriendlyByteBuf) {
@@ -659,8 +635,6 @@ class HorseState : RidingBehaviourState() {
sprintToggleable.set(buffer.readBoolean(), forced = true)
inAir.set(buffer.readBoolean(), forced = true)
jumpTicks.set(buffer.readInt(), forced = true)
sprintTickTimer.set(buffer.readInt(), forced = true)
forwardHeldLastTick.set(buffer.readBoolean(), forced = true)
}
override fun reset() {
@@ -670,8 +644,6 @@ class HorseState : RidingBehaviourState() {
sprintToggleable.set(false, forced = true)
inAir.set(false, forced = true)
jumpTicks.set(0, forced = true)
sprintTickTimer.set(0, forced = true)
forwardHeldLastTick.set(false, forced = true)
}
override fun copy() = HorseState().also {
@@ -682,8 +654,6 @@ class HorseState : RidingBehaviourState() {
it.sprintToggleable.set(this.sprintToggleable.get(), forced = true)
it.inAir.set(this.inAir.get(), forced = true)
it.jumpTicks.set(this.jumpTicks.get(), forced = true)
it.sprintTickTimer.set(this.sprintTickTimer.get(), forced = true)
it.forwardHeldLastTick.set(this.forwardHeldLastTick.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
@@ -88,6 +88,7 @@ abstract class OneToOneFileStoreAdapter<S>(
result
}
else {
storeClass.getConstructor(UUID::class.java).newInstance(uuid)
var result = storeClass.getConstructor(UUID::class.java).newInstance(uuid)
save(storeClass, uuid, serialize(result, registryAccess))
oldFile.delete()
@@ -19,6 +19,7 @@ import net.minecraft.server.level.ServerLevel
import net.minecraft.tags.FluidTags
import net.minecraft.util.Mth
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.*
import net.minecraft.world.level.block.Block
@@ -174,7 +175,7 @@ class HeartyGrainsBlock(settings: Properties) : CropBlock(settings), SimpleWater
UPDATE_CLIENTS
)
}
else if (stateAbove.hasProperty(HALF) && stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
else if (stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
world.setBlock(
abovePos,
stateAbove.setValue(AGE, newAge),
@@ -34,7 +34,6 @@ 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.Explosion
import net.minecraft.world.level.Level
import net.minecraft.world.level.LevelAccessor
import net.minecraft.world.level.LevelReader
@@ -56,10 +55,9 @@ import net.minecraft.world.phys.shapes.VoxelShape
import java.util.*
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
import net.minecraft.world.level.gameevent.GameEvent
import java.util.function.BiConsumer
@Suppress("OVERRIDE_DEPRECATION", "DEPRECATION")
class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWaterloggedBlock {
class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWaterloggedBlock, PreEmptsExplosion {
companion object {
val CODEC = simpleCodec(::PastureBlock)
@@ -215,19 +213,9 @@ class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWater
return super.playerWillDestroy(world, pos, state, player)
}
override fun onExplosionHit(
state: BlockState,
level: Level,
pos: BlockPos,
explosion: Explosion,
dropConsumer: BiConsumer<ItemStack?, BlockPos?>
) {
val interaction = explosion.blockInteraction
if (interaction == Explosion.BlockInteraction.DESTROY || interaction == Explosion.BlockInteraction.DESTROY_WITH_DECAY) {
val blockEntity = level.getBlockEntity(pos) as? PokemonPastureBlockEntity ?: return
blockEntity.onBroken()
}
super.onExplosionHit(state, level, pos, explosion, dropConsumer)
override fun whenExploded(world: Level, state: BlockState, pos: BlockPos) {
val blockEntity = world.getBlockEntity(pos) as? PokemonPastureBlockEntity ?: return
blockEntity.onBroken()
}
override fun <T : BlockEntity?> getTicker(world: Level, state: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? {
@@ -0,0 +1,17 @@
/*
* 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
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
interface PreEmptsExplosion {
fun whenExploded(world: Level, state: BlockState, pos: BlockPos)
}
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.block
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
import com.cobblemon.mod.common.util.isServerSide
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.dispenser.DispenseItemBehavior
@@ -264,39 +263,23 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings) {
val isGlassBottle = itemStack.`is`(Items.GLASS_BOTTLE)
val isHoneyBottle = itemStack.`is`(Items.HONEY_BOTTLE)
if (isGlassBottle && isAtMaxAge(state)) {
if (level.isClientSide) return ItemInteractionResult.SUCCESS
if (isGlassBottle && !isAtMinAge(state)) {
// Decrement stack if not in creative mode
itemStack.consume(1, player)
// Give player a honey bottle
if (stack.isEmpty) {
// Replace the consumed empty bottle with a honey bottle
player.setItemInHand(hand, ItemStack(Items.HONEY_BOTTLE));
} else {
player.addItem(Items.HONEY_BOTTLE.defaultInstance)
}
// Give player honey bottle for now
player.addItem(Items.HONEY_BOTTLE.defaultInstance)
level.playSound(null, pos, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS)
level.setBlock(pos, state.setValue(AGE, 0), UPDATE_CLIENTS)
level.setBlock(pos, state.setValue(AGE, 0), 2)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
return ItemInteractionResult.SUCCESS
} else if (isHoneyBottle && !isAtMaxAge(state)) {
if (level.isClientSide) return ItemInteractionResult.SUCCESS
// Decrement stack if not in creative mode
if (!player.isCreative) {
itemStack.consume(1, player)
if (stack.isEmpty) {
// Replace the consumed honey bottle with an empty bottle
player.setItemInHand(hand, ItemStack(Items.GLASS_BOTTLE));
} else {
player.addItem(Items.GLASS_BOTTLE.defaultInstance)
}
}
itemStack.consume(1, player)
level.playSound(null, pos, SoundEvents.HONEY_BLOCK_PLACE, SoundSource.BLOCKS)
level.setBlock(pos, state.setValue(AGE, 2), UPDATE_CLIENTS)
level.setBlock(pos, state.setValue(AGE, 2), 2)
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
return ItemInteractionResult.SUCCESS
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.block.campfirepot
import com.cobblemon.mod.common.CobblemonMenuType
import com.cobblemon.mod.common.CobblemonRecipeBookTypes.COOKING_POT
import com.cobblemon.mod.common.CobblemonRecipeTypes
import com.cobblemon.mod.common.api.cooking.Seasonings
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity
@@ -212,7 +211,7 @@ class CookingPotMenu : RecipeBookMenu<CraftingInput, CookingPotRecipeBase>, Cont
}
override fun getRecipeBookType(): RecipeBookType {
return COOKING_POT
return RecipeBookType.valueOf("COOKING_POT")
}
override fun shouldMoveToInventory(slotIndex: Int): Boolean {
@@ -138,8 +138,7 @@ abstract class BattleGimmickButton(gimmick: ShowdownMoveset.Gimmick, val x: Floa
pp = gimmickTemplate?.pp ?: moveTemplate.pp,
priority = gimmickTemplate?.priority ?: moveTemplate.priority,
critRatio = gimmickTemplate?.critRatio ?: moveTemplate.critRatio,
effectChances = gimmickTemplate?.effectChances ?: moveTemplate.effectChances,
weight = gimmickTemplate?.weight ?: moveTemplate.weight
effectChances = gimmickTemplate?.effectChances ?: moveTemplate.effectChances
)
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.gui.pc
import com.cobblemon.mod.common.CobblemonNetwork
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.gui.getPixelRGB
import com.cobblemon.mod.common.api.storage.StorePosition
import com.cobblemon.mod.common.api.storage.party.PartyPosition
import com.cobblemon.mod.common.api.storage.pc.PCPosition
@@ -283,6 +284,20 @@ class StorageWidget(
height = 189,
alpha = if (screenLoaded) 1F else ((pcGui.ticksElapsed).toFloat() / 10F).coerceIn(0F, 1F)
)
} else {
val rgb = getPixelRGB(x + (SCREEN_WIDTH / 2), y + (SCREEN_HEIGHT / 2))
blitk(
matrixStack = matrices,
texture = screenGlowResource,
x = x - 17,
y = y - 17,
width = 208,
height = 189,
red = rgb.first / 255F,
green = rgb.second / 255F,
blue = rgb.third / 255F,
alpha = if (screenLoaded) 1F else ((pcGui.ticksElapsed).toFloat() / 10F).coerceIn(0F, 1F)
)
}
blitk(
@@ -592,10 +592,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
}
private fun switchForm(nextIndex: Boolean) {
if (visibleForms.isEmpty() || currentEntry == null) {
return
}
selectedPoseIndex = 0
if (nextIndex) {
@@ -606,8 +602,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
else selectedFormIndex = visibleForms.lastIndex
}
selectedFormIndex = selectedFormIndex.coerceIn(0, visibleForms.lastIndex)
setupButtons(currentEntry!!, visibleForms[selectedFormIndex])
updateAspects()
}
@@ -16,8 +16,8 @@ import com.mojang.blaze3d.platform.InputConstants
object RidingFreelookBinding : CobblemonBlockingKeyBinding(
"key.cobblemon.ridingfreelook",
InputConstants.Type.KEYSYM,
InputConstants.KEY_LALT,
InputConstants.Type.MOUSE,
InputConstants.MOUSE_BUTTON_MIDDLE,
KeybindCategories.COBBLEMON_CATEGORY
) {
override fun onTick() {
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TinkatinkModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("tinkatink")
override val head = getPart("head")
override val rightArm = getPart("arm_right")
override val leftArm = getPart("arm_left")
override val rightLeg = getPart("leg_right")
override val leftLeg = getPart("leg_left")
override var portraitScale = 2.0F
override var portraitTranslation = Vec3(0.0, -1.01, 0.0)
override var profileScale = 1.0F
override var profileTranslation = Vec3(0.0, 0.25, 0.0)
lateinit var standing: Pose
lateinit var walking: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
lateinit var shoulderLeft: Pose
lateinit var shoulderRight: Pose
val shoulderOffset = 1
override val cryAnimation = CryProvider { bedrockStateful("tinkatink", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("tinkatink", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("tinkatink", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatink", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatink", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatink", "battle_idle")
)
)
shoulderLeft = registerPose(
poseType = PoseType.SHOULDER_LEFT,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatink", "shoulder_left")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
)
)
shoulderRight = registerPose(
poseType = PoseType.SHOULDER_RIGHT,
quirks = arrayOf(blink),
condition = { !it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatink", "shoulder_right")
),
transformedParts = arrayOf(
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("tinkatink", "faint") else null
}
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen9
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TinkatuffModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("tinkatuff")
override val head = getPart("head")
override val rightArm = getPart("arm_right")
override val leftArm = getPart("arm_left")
override val rightLeg = getPart("leg_right")
override val leftLeg = getPart("leg_left")
override var portraitScale = 1.9F
override var portraitTranslation = Vec3(0.0, -0.41, 0.0)
override var profileScale = 0.9F
override var profileTranslation = Vec3(0.0, 0.4, 0.0)
lateinit var standing: Pose
lateinit var walking: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
override val cryAnimation = CryProvider { bedrockStateful("tinkatuff", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("tinkatuff", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("tinkatuff", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
condition = { !it.isBattling },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatuff", "ground_idle")
)
)
walking = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatuff", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
singleBoneLook(),
bedrock("tinkatuff", "battle_idle")
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("tinkatuff", "faint") else null
}
@@ -477,6 +477,8 @@ object VaryingModelRepository {
inbuilt("illumise", ::IllumiseModel)
inbuilt("yamper", ::YamperModel)
inbuilt("boltund", ::BoltundModel)
inbuilt("tinkatink", ::TinkatinkModel)
inbuilt("tinkatuff", ::TinkatuffModel)
inbuilt("fuecoco", :: FuecocoModel)
inbuilt("crocalor", :: CrocalorModel)
inbuilt("skeledirge", :: SkeledirgeModel)
@@ -14,9 +14,6 @@ import com.cobblemon.mod.common.CobblemonBehaviours
import com.cobblemon.mod.common.CobblemonCallbacks
import com.cobblemon.mod.common.CobblemonCosmeticItems
import com.cobblemon.mod.common.CobblemonMechanics
import com.cobblemon.mod.common.CobblemonMovesetBuilders
import com.cobblemon.mod.common.CobblemonPartyCompositions
import com.cobblemon.mod.common.CobblemonPartyPools
import com.cobblemon.mod.common.CobblemonRideSettings
import com.cobblemon.mod.common.CobblemonUnlockableWallpapers
import com.cobblemon.mod.common.api.abilities.Abilities
@@ -81,15 +78,12 @@ object CobblemonDataProvider : DataProvider {
this.register(SpeciesFeatureAssignments, reloadable = false)
this.register(ActionEffects, reloadable = true)
this.register(Moves, reloadable = false)
this.register(CobblemonMovesetBuilders, reloadable = false)
this.register(Abilities, reloadable = false)
this.register(CobblemonBehaviours, reloadable = false)
this.register(PokemonSpecies, reloadable = false)
this.register(SpeciesAdditions, reloadable = false)
this.register(PokeBalls, reloadable = false)
this.register(PropertiesCompletionProvider, reloadable = false)
this.register(CobblemonPartyPools, reloadable = false)
this.register(CobblemonPartyCompositions, reloadable = false)
this.register(SpawnDetailPresets, reloadable = true)
this.register(CobblemonSpawnRules, reloadable = true)
this.register(CobblemonMechanics, reloadable = true)
@@ -39,16 +39,15 @@ class FollowWalkTargetTask(
private var lookTargetPos: BlockPos? = null
private var speed = 0f
override fun checkExtraStartConditions(level: ServerLevel, entity: PathfinderMob): Boolean {
override fun checkExtraStartConditions(arg: ServerLevel, arg2: PathfinderMob): Boolean {
if (this.pathUpdateCountdownTicks > 0) {
--this.pathUpdateCountdownTicks
return false
} else {
val brain = entity.brain
val brain = arg2.brain
val walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get()
val hasReached = this.hasReached(entity, walkTarget)
resetPathUpdateCountdownTicks(entity)
if (!hasReached && this.hasFinishedPath(entity, walkTarget, level.gameTime)) {
val hasReached = this.hasReached(arg2, walkTarget)
if (!hasReached && this.hasFinishedPath(arg2, walkTarget, arg.gameTime)) {
this.lookTargetPos = walkTarget.target.currentBlockPosition()
return true
} else {
@@ -62,10 +61,6 @@ class FollowWalkTargetTask(
}
}
fun resetPathUpdateCountdownTicks(entity: PathfinderMob) {
pathUpdateCountdownTicks = entity.random.nextInt(20) + 20
}
override fun canStillUse(arg: ServerLevel, arg2: PathfinderMob, l: Long): Boolean {
if (this.path != null && this.lookTargetPos != null) {
val optional = arg2.brain.getMemory(MemoryModuleType.WALK_TARGET)
@@ -80,7 +75,7 @@ class FollowWalkTargetTask(
override fun stop(world: ServerLevel, entity: PathfinderMob, l: Long) {
val walkTarget = entity.brain.getMemory(MemoryModuleType.WALK_TARGET).orElse(null)
if (walkTarget != null && !this.hasReached(entity, walkTarget) && entity.navigation.isStuck) {
resetPathUpdateCountdownTicks(entity)
this.pathUpdateCountdownTicks = world.getRandom().nextInt(40)
}
entity.navigation.stop()
@@ -186,7 +186,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
val blockState = this.world.getBlockState(target)
val path = if (!blockState.isSolid
|| (blockState.`is`(BlockTags.LEAVES) && blockState.block == CobblemonBlocks.SACCHARINE_LEAVES && pather.canPathThroughSaccLeaves())) {
|| (blockState.`is`(BlockTags.LEAVES) && blockState.block == CobblemonBlocks.SACCHARINE_LEAVES && (this.entity as PokemonEntity).canPathThroughSaccLeaves())) {
findPath(target, distance)
} else {
blockPos = target.above()
@@ -269,7 +269,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
// If we can fly and we're airborne, return the current Y position
return vec.y
}
if (world.getBlockState(blockPos).block == CobblemonBlocks.SACCHARINE_LEAVES && pather.canPathThroughSaccLeaves()) {
if (world.getBlockState(blockPos).block == CobblemonBlocks.SACCHARINE_LEAVES && (this.entity as PokemonEntity).canPathThroughSaccLeaves()) {
return vec.y + 0.5
}
return if ((canFloat()) && blockGetter.getFluidState(blockPos).`is`(FluidTags.WATER)) vec.y + 0.5 else super.getGroundY(vec)
@@ -191,7 +191,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
}
}
} else {
isNoGravity = false
setNoGravity(false)
deltaMovement = Vec3.ZERO
}
}
@@ -547,11 +547,6 @@ open class PokemonEntity(
ifRidingAvailable { _, _, state -> pokemon.rideStamina = state.stamina.get() }
ridingController?.context?.state?.reset()
ridingAnimationData.clear()
// reset riding orientation
if (this is OrientationControllable) {
this.orientationController.reset()
}
}
}
@@ -10,11 +10,8 @@ package com.cobblemon.mod.common.entity.pokemon.ai.sensors
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.getMemorySafely
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities
import net.minecraft.world.entity.ai.sensing.Sensor
@@ -31,17 +28,8 @@ class DefendOwnerSensor : Sensor<PokemonEntity>(10) {
}
private fun setNearestAttacker(entity: PokemonEntity, visibleMobs: NearestVisibleLivingEntities, owner: LivingEntity) {
val nearestAttacker = visibleMobs.findClosest { livingEntity ->
// Prevents Pokémons from attacking players as owned Pokémons are currently invulnerable
if (livingEntity is ServerPlayer) return@findClosest false
if (livingEntity.lastHurtMob == owner) return@findClosest true
if (livingEntity is Mob && livingEntity.target == owner) return@findClosest true
val mobAttackTarget = livingEntity.brain.getMemorySafely(MemoryModuleType.ATTACK_TARGET)
if (mobAttackTarget.isPresent && mobAttackTarget.get() == owner) return@findClosest true
return@findClosest false
val nearestAttacker = visibleMobs.findClosest { mob ->
mob.lastHurtMob == owner
}.map { mob -> mob as LivingEntity }
entity.brain.setMemory(CobblemonMemories.NEAREST_VISIBLE_ATTACKER, nearestAttacker)
@@ -10,10 +10,18 @@ package com.cobblemon.mod.common.entity.pokemon.ai.tasks
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.google.common.collect.ImmutableMap
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.ai.behavior.Behavior
import net.minecraft.world.entity.ai.behavior.OneShot
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.entity.ai.targeting.TargetingConditions
object DefendOwnerTask {
fun create(): OneShot<PokemonEntity> {
@@ -52,9 +52,8 @@ object PlaceHoneyInHiveTask {
if (blockEntity.isFull) {
// Erase Hive memory and give the bee a moment to locate a new hive
entity.brain.eraseMemory(CobblemonMemories.HIVE_LOCATION)
} else {
blockEntity.addOccupant(entity)
}
blockEntity.addOccupant(entity)
}
return@Trigger true
@@ -13,11 +13,7 @@ import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
import com.cobblemon.mod.common.api.types.ElementalTypes
import com.cobblemon.mod.common.battles.MoveTarget
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.writeEnumConstant
import com.cobblemon.mod.common.util.writeString
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
class MovesRegistrySyncPacket(moves: List<MoveTemplate>) : DataRegistrySyncPacket<MoveTemplate, MovesRegistrySyncPacket>(moves) {
@@ -37,7 +33,6 @@ class MovesRegistrySyncPacket(moves: List<MoveTemplate>) : DataRegistrySyncPacke
buffer.writeDouble(entry.critRatio)
buffer.writeInt(entry.effectChances.size)
entry.effectChances.forEach { chance -> buffer.writeDouble(chance) }
buffer.writeFloat(entry.weight)
}
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): MoveTemplate {
@@ -55,21 +50,7 @@ class MovesRegistrySyncPacket(moves: List<MoveTemplate>) : DataRegistrySyncPacke
repeat(buffer.readInt()) {
effectChances += buffer.readDouble()
}
val weight = buffer.readFloat()
return MoveTemplate(
name = name,
num = num,
elementalType = type,
damageCategory = damageCategory,
power = power,
target = target,
accuracy = accuracy,
pp = pp,
priority = priority,
critRatio = critRatio,
effectChances = effectChances.toTypedArray(),
weight = weight
)
return MoveTemplate(name, num, type, damageCategory, power, target, accuracy, pp, priority, critRatio, effectChances.toTypedArray())
}
override fun synchronizeDecoded(entries: Collection<MoveTemplate>) {
@@ -104,10 +104,6 @@ class FormData(
private var _baseAI: MutableList<BehaviourConfig>? = null,
@SerializedName("ai")
private var _ai: MutableList<BehaviourConfig>? = null,
@SerializedName("signatureMoves")
private var _signatureMoves: MutableList<MoveTemplate>? = null,
@SerializedName("defaultWildMovesetBuilder")
private val _defaultWildMovesetBuilder: ResourceLocation? = null,
val requiredMove: String? = null,
val requiredItem: String? = null,
/** For forms that can accept different items (e.g. Arceus-Grass: Meadow Plate or Grassium-Z). */
@@ -239,10 +235,6 @@ class FormData(
get() = _baseAI ?: species.baseAI
val ai: List<BehaviourConfig>
get() = _ai ?: species.ai
val signatureMoves: List<MoveTemplate>
get() = _signatureMoves ?: species.signatureMoves
val defaultWildMovesetBuilder: ResourceLocation
get() = _defaultWildMovesetBuilder ?: species.defaultWildMovesetBuilder
fun eyeHeight(entity: PokemonEntity): Float {
return this.resolveEyeHeight(entity) ?: return this.species.eyeHeight(entity)
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.pokemon
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonMovesetBuilders
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.CobblemonNetwork.sendPacketToPlayers
import com.cobblemon.mod.common.CobblemonSounds
@@ -35,7 +34,6 @@ import com.cobblemon.mod.common.api.moves.Move
import com.cobblemon.mod.common.api.moves.MoveSet
import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.api.pokeball.PokeBalls
import com.cobblemon.mod.common.api.pokemon.Natures
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
@@ -593,9 +591,6 @@ open class Pokemon : ShowdownIdentifiable {
onChange(MarkingsUpdatePacket({ this }, value))
}
// Last flower fed to a Mooshtank
var lastFlowerFed: ItemStack = ItemStack.EMPTY
fun asRenderablePokemon() = RenderablePokemon(species, aspects, if (heldItemVisible) heldItem else ItemStack.EMPTY)
/**
@@ -678,7 +673,7 @@ open class Pokemon : ShowdownIdentifiable {
* Whether this Pokémon's held item can be dropped by its AI.
*/
internal var canDropHeldItem: Boolean = false
get() = field && !heldItem.isEmpty
get() = field || heldItem.isEmpty
val riding: RidingProperties
get() = this.form.riding
@@ -1561,8 +1556,10 @@ open class Pokemon : ShowdownIdentifiable {
originalTrainer = fakeTrainerName
}
fun refreshOriginalTrainer() {
when (originalTrainerType) {
fun refreshOriginalTrainer()
{
when (originalTrainerType)
{
OriginalTrainerType.PLAYER -> {
UUID.fromString(originalTrainer)?.let { uuid ->
server()?.profileCache?.get(uuid)?.orElse(null)?.name?.let {
@@ -1579,7 +1576,8 @@ open class Pokemon : ShowdownIdentifiable {
}
}
fun removeOriginalTrainer() {
fun removeOriginalTrainer()
{
originalTrainer = null
originalTrainerType = OriginalTrainerType.NONE
originalTrainerName = null
@@ -1621,11 +1619,14 @@ open class Pokemon : ShowdownIdentifiable {
species = species
checkGender()
if (moveSet.getMoves().isEmpty()) {
initializeMovesetFromDefault()
initializeMoveset()
}
return this
}
// Last flower fed to a Mooshtank
var lastFlowerFed: ItemStack = ItemStack.EMPTY
fun checkGender() {
var reassess = false
if (form.maleRatio !in 0F..1F && gender != Gender.GENDERLESS) {
@@ -1801,20 +1802,6 @@ open class Pokemon : ShowdownIdentifiable {
moveSet.update()
}
fun initializeMovesetFromDefault() {
initializeMovesetFrom(movesetBuilder = CobblemonMovesetBuilders.getOrThrow(form.defaultWildMovesetBuilder))
}
fun initializeMovesetFrom(movesetBuilder: MovesetBuilder) {
val newMoveset = movesetBuilder.build(form = form, level = level)
moveSet.copyFrom(newMoveset)
}
@Deprecated(
message = "Will be removed within potentially 1 title update",
replaceWith = ReplaceWith("initializeMovesetFromDefault"),
level = DeprecationLevel.ERROR
)
fun initializeMoveset(preferLatest: Boolean = true) {
val possibleMoves = form.moves.getLevelUpMovesUpTo(level).toMutableList()
moveSet.doWithoutEmitting {
@@ -22,7 +22,6 @@ import com.cobblemon.mod.common.api.drop.DropTable
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addSpeciesFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.moves.MoveTemplate
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffect
@@ -43,7 +42,6 @@ import com.cobblemon.mod.common.net.IntSize
import com.cobblemon.mod.common.pokemon.abilities.HiddenAbility
import com.cobblemon.mod.common.pokemon.ai.PokemonBehaviour
import com.cobblemon.mod.common.pokemon.lighthing.LightingData
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readEntityDimensions
import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.readIdentifier
@@ -113,8 +111,6 @@ class Species : ClientDataSynchronizer<Species>, ShowdownIdentifiable {
var implemented = false
var baseAI: MutableList<BehaviourConfig>? = null
var ai = mutableListOf<BehaviourConfig>()
var signatureMoves = mutableListOf<MoveTemplate>()
var defaultWildMovesetBuilder = cobblemonResource("wild")
/**
* The height in decimeters
@@ -87,7 +87,6 @@ object DataKeys {
const val POKEMON_PROPERTIES_MOVES = "Moves"
const val POKEMON_PROPERTIES_HELDITEM = "HeldItem"
const val POKEMON_PROPERTIES_MOVESET_BUILDERS = "MovesetBuilders"
// Entity effects
const val ENTITY_EFFECTS = "EntityEffects"
@@ -1,42 +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.util
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.molang.ExpressionLike
/**
* An IntRange where the minimum and maximum values are defined by MoLang expressions. When deserializing from
* JSON the [com.cobblemon.mod.common.util.adapters.ScriptableIntRangeAdapter] will figure out if it's a single
* value in which case it's not using any scripting stuff. Otherwise, if it's an object with "min" and "max" properties
* it will respect them as expressions.
*
* @author Hiroku
* @since December 15th, 2025
*/
class ScriptableIntRange(
val min: ExpressionLike = "0".asExpressionLike(),
val max: ExpressionLike = "0".asExpressionLike()
) {
constructor(min: Int, max: Int): this(
min = min.toString().asExpressionLike(),
max = max.toString().asExpressionLike()
)
fun resolve(runtime: MoLangRuntime): IntRange {
val minimum = min.resolveInt(runtime)
val maximum = max.resolveInt(runtime)
if (minimum > maximum) {
Cobblemon.LOGGER.error("ScriptableIntRange(${min.getString()}, ${max.getString()}) resolved a minimum ($minimum) greater than maximum ($maximum). Returning empty range.")
return IntRange.EMPTY
}
return minimum..maximum
}
}
@@ -1,26 +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.util.adapters
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type
object MovesetBuilderAdapter : JsonDeserializer<MovesetBuilder> {
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): MovesetBuilder {
val jsonObject = json.asJsonObject
val type = jsonObject.get("type")?.asString ?: "cobblemon:default"
val clazz = MovesetBuilder.movesetBuilderTypes[type.asIdentifierDefaultingNamespace()]
?: throw IllegalArgumentException("Unknown MovesetBuilder type: $type")
return context.deserialize(json, clazz)
}
}
@@ -1,23 +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.util.adapters
import com.cobblemon.mod.common.CobblemonMovesetBuilders
import com.cobblemon.mod.common.api.moves.MovesetBuilder
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type
object MovesetBuilderReferenceAdapter : JsonDeserializer<MovesetBuilder> {
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): MovesetBuilder {
return CobblemonMovesetBuilders.getOrThrow(json.asString.asIdentifierDefaultingNamespace())
}
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.util.adapters
import com.cobblemon.mod.common.api.npc.NPCPartyProvider
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
@@ -17,8 +16,8 @@ import java.lang.reflect.Type
object NPCPartyProviderAdapter : JsonDeserializer<NPCPartyProvider> {
override fun deserialize(json: JsonElement, type: Type, ctx: JsonDeserializationContext): NPCPartyProvider {
val typeName = (if (json.isJsonPrimitive) json.asString else json.asJsonObject.get("type").asString).asIdentifierDefaultingNamespace()
return NPCPartyProvider.types[typeName]?.invoke()?.also { it.loadFromJSON(json) }
val typeName = if (json.isJsonPrimitive) json.asString else json.asJsonObject.get("type").asString
return NPCPartyProvider.types[typeName]?.invoke(typeName)?.also { it.loadFromJSON(json) }
?: throw IllegalStateException("Unable to find party provider by type: $typeName")
}
}
@@ -1,53 +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.util.adapters
import com.cobblemon.mod.common.util.ScriptableIntRange
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 java.lang.reflect.Type
/**
* Parses a [ScriptableIntRange] by two paths. One is if it's a primitive in which
* case they're just doing a normal [IntRange] and it will parse it using the same
* method as IntRange normally gets and then returns a ScriptableIntRange of literals.
*
* The other path is if they provide an object with "min" and "max" in which case
* each property is deserialized as an [ExpressionLike].
*
* @author Hiroku
* @since December 15th, 2025
*/
object ScriptableIntRangeAdapter : JsonDeserializer<ScriptableIntRange> {
override fun deserialize(
json: JsonElement,
typeOfT: Type,
context: JsonDeserializationContext
): ScriptableIntRange {
if (json is JsonPrimitive) {
IntRangeAdapter.deserialize(json, typeOfT, context).let {
return ScriptableIntRange(
it.first.toString().asExpressionLike(),
it.last.toString().asExpressionLike()
)
}
} else {
val obj = json.asJsonObject
val min = obj.get("min").asString
val max = obj.get("max").asString
return ScriptableIntRange(
min.toString().asExpressionLike(),
max.toString().asExpressionLike()
)
}
}
}
@@ -1,29 +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.util.adapters
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type
/**
* A simple adapter that maps string values to objects based on a provided mapping.
*
* I could swear I already made something like this before.
*
* @author Hiroku
* @since December 5th, 2025
*/
class StringToObjectAdapter<T>(
val mapping: MutableMap<String, T>
) : JsonDeserializer<T> {
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): T = mapping[json.asString]
?: throw IllegalArgumentException("Unknown mapping for string: ${json.asString}")
}
@@ -297,11 +297,6 @@
"1.0833": [0, 0, 0]
}
}
},
"sound_effects": {
"0.25": {
"effect": "pokemon.ditto.cry"
}
}
},
"animation.ditto.blink": {
@@ -3,7 +3,7 @@
"animations": {
"animation.metagross.ground_idle": {
"loop": true,
"animation_length": 0,
"animation_length": 11.4167,
"bones": {
"body2": {
"position": [0, -11.9, 0]
@@ -299,14 +299,6 @@
"rotation": [0, 0, 15]
}
}
},
"animation.eelektrik.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0417": {
"effect": "pokemon.eelektrik.cry"
}
}
}
}
}
@@ -869,14 +869,6 @@
"position": [-0.1, 0, 0]
}
}
},
"animation.eelektross.cry": {
"animation_length": 1.25,
"sound_effects": {
"0.0417": {
"effect": "pokemon.eelektross.cry"
}
}
}
}
}
@@ -84,7 +84,7 @@
"position": [0, "0+Math.cos((query.anim_time) * 90 * 8 - 60) * -0.1", 0]
},
"hair3": {
"rotation": ["-2+Math.cos((query.anim_time) * 90 * 8 - 100) * 3", 0, 0]
"rotation": ["0+Math.cos((query.anim_time) * 90 * 8 - 100) * 3", 0, 0]
},
"hair": {
"rotation": ["0+Math.cos((query.anim_time) * 90 * 8 - 120) * 10", 12.5, "0+Math.cos((query.anim_time) * 90 * 4 - 180) * 10"]
@@ -356,7 +356,7 @@
"position": [-1.63659, -1.07651, 3.16823]
},
"arm_right": {
"rotation": [-99.86576, -52.80463, 0.06108]
"rotation": [-80.89079, -82.69097, -6.55875]
},
"finger_right": {
"rotation": [0, 0, 17.5]
@@ -375,21 +375,6 @@
},
"arm_hammer_left": {
"rotation": [-85, 100, 0]
},
"hand_right": {
"rotation": [0, 0, -22.5]
},
"brow_right": {
"position": [0, -0.75, 0]
},
"brow_left": {
"position": [0, -0.75, 0]
},
"eyes_ditto": {
"position": [0, 0, 0.1]
},
"eyes_blink_ditto": {
"position": [0, 0, -0.1]
}
}
},
@@ -475,26 +460,40 @@
"1.875": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.375": [0, 0, 0],
"0.4167": [0, 0, -0.125],
"0.625": [0, 0, -0.125],
"0.6667": [0, 0, 0],
"0.8333": [0, 0, 0],
"0.875": [0, 0, -0.125],
"1.5833": [0, 0, -0.125],
"1.625": [0, 0, 0],
"1.7083": [0, 0, 0],
"1.75": [0, 0, -0.125]
}
},
"eyelid_left": {
"position": {
"0.375": [0, 0, 0],
"0.4167": [0, 0, -0.1],
"0.625": [0, 0, -0.1],
"0.4167": [0, 0, -0.125],
"0.625": [0, 0, -0.125],
"0.6667": [0, 0, 0],
"0.8333": [0, 0, 0],
"0.875": [0, 0, -0.1],
"1.5833": [0, 0, -0.1],
"1.625": [0, 0, 1],
"0.875": [0, 0, -0.125],
"1.5833": [0, 0, -0.125],
"1.625": [0, 0, 0],
"1.7083": [0, 0, 0],
"1.75": [0, 0, -0.1]
"1.75": [0, 0, -0.125]
}
},
"mouth_open_cry": {
"mouth_open": {
"position": {
"0.8333": [0, 0, 0],
"0.875": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.875": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"1.9167": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
"0.875": [0, 0, -0.125],
"1.875": [0, 0, -0.125],
"1.9167": [0, 0, 0]
}
},
"arm_left": {
@@ -557,6 +556,13 @@
"1.75": [0, 0, 0]
}
},
"eye_right": {
"scale": {
"1.5833": [1, 1, 1],
"1.625": [1.4, 1.4, 3.3],
"1.7083": [1, 1, 1]
}
},
"eye_left": {
"scale": {
"1.5833": [1, 1, 1],
@@ -716,55 +722,6 @@
"1.7083": [1, 1, 1]
}
},
"leg_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.2917": [0, -20, -2.5],
"0.4167": [-5.68, -13.75, -2.5],
"0.5833": [-32.36, -7.5, -2.5],
"0.7083": [-40.5, 2.5, -2.5],
"0.75": [-33.83, 2.5, -2.5],
"0.8333": [-30.5, 2.5, -2.5]
},
"position": {
"0.4167": [0, 0, 0],
"0.5833": [0, 0, -0.75],
"1.5833": [0, 0, -0.75],
"1.625": [1.25, 0, -0.75],
"1.75": [0, 0, 0]
}
},
"arm_hammer_left": {
"rotation": {
"0.0": [0, 0, 17.5],
"0.25": [0, -25, 5],
"0.4167": [0, -32.5, 3.5],
"0.5": [-11.25, 40.75, -16.75],
"0.5833": [-22.5, 46.75, -37],
"0.7083": [-25, 44, -40.75]
}
},
"eye_right": {
"scale": {
"1.5833": [1, 1, 1],
"1.625": [1.4, 1.4, 3.3],
"1.7083": [1, 1, 1]
}
},
"eyelid_right": {
"position": {
"0.375": [0, 0, 0],
"0.4167": [0, 0, -0.1],
"0.625": [0, 0, -0.1],
"0.6667": [0, 0, 0],
"0.8333": [0, 0, 0],
"0.875": [0, 0, -0.1],
"1.5833": [0, 0, -0.1],
"1.625": [0, 0, 1],
"1.7083": [0, 0, 0],
"1.75": [0, 0, -0.1]
}
},
"arm_right": {
"rotation": {
"0.0": [0, 0, -20],
@@ -796,6 +753,24 @@
"finger_right3": {
"rotation": [0, 0, -22.5]
},
"leg_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.2917": [0, -20, -2.5],
"0.4167": [-5.68, -13.75, -2.5],
"0.5833": [-32.36, -7.5, -2.5],
"0.7083": [-40.5, 2.5, -2.5],
"0.75": [-33.83, 2.5, -2.5],
"0.8333": [-30.5, 2.5, -2.5]
},
"position": {
"0.4167": [0, 0, 0],
"0.5833": [0, 0, -0.75],
"1.5833": [0, 0, -0.75],
"1.625": [1.25, 0, -0.75],
"1.75": [0, 0, 0]
}
},
"leg_right": {
"rotation": {
"0.0": [0, 0, 0],
@@ -814,146 +789,33 @@
"1.75": [-0.5, 0, 0]
}
},
"brow_left": {
"position": {
"0.375": [0, 0, 0],
"0.4167": [0, -0.75, 0],
"0.625": [0, -0.75, 0],
"0.6667": [0, 0, 0],
"0.8333": [0, 0, 0],
"0.875": [0, -0.75, 0],
"1.5833": [0, -0.75, 0],
"1.625": [0, 0, 0],
"1.7083": [0, 0, 0],
"1.75": [0, -0.75, 0]
}
},
"brow_right": {
"position": {
"0.375": [0, 0, 0],
"0.4167": [0, -0.75, 0],
"0.625": [0, -0.75, 0],
"0.6667": [0, 0, 0],
"0.8333": [0, 0, 0],
"0.875": [0, -0.75, 0],
"1.5833": [0, -0.75, 0],
"1.625": [0, 0, 0],
"1.7083": [0, 0, 0],
"1.75": [0, -0.75, 0]
}
},
"mouth_closed": {
"position": {
"0.8333": [0, 0, 0],
"0.875": {"pre": [0, 0, 0], "post": [0, -0.5, 0]},
"1.875": {"pre": [0, -0.5, 0], "post": [0, -0.5, 0]},
"1.9167": {"pre": [0, -0.5, 0], "post": [0, 0, 0]}
}
},
"mouth_lip_top": {
"position": {
"0.8333": [0, 0, 0],
"0.875": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.875": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"1.9167": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eyes_ditto": {
"position": {
"0.375": [0, 0, 0],
"0.4167": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"0.625": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"0.6667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"0.8333": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.875": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.5833": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.75": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
},
"scale": {
"1.5833": [1, 1, 1],
"1.625": [1.4, 1.4, 3.3],
"1.7083": [1, 1, 1]
}
},
"eyes_blink_ditto": {
"position": {
"0.375": [0, 0, 0],
"0.4167": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"0.625": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"0.6667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"0.8333": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.875": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.5833": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"1.75": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
}
},
"mouth_ditto": {
"position": {
"0.8333": [0, 0, 0],
"0.875": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.875": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"1.9167": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"mouth_open_ditto": {
"position": {
"0.8333": [0, 0, 0],
"0.875": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.875": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"1.9167": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
"arm_hammer_left": {
"rotation": {
"0.0": [0, 0, 17.5],
"0.25": [0, -25, 5],
"0.4167": [0, -32.5, 3.5],
"0.5": [-11.25, 40.75, -16.75],
"0.5833": [-22.5, 46.75, -37],
"0.7083": [-25, 44, -40.75]
}
}
}
},
"animation.tinkatink.blink": {
"animation_length": 0.1667,
"animation_length": 0.16667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"brow_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"brow_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"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]}
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
@@ -961,6 +823,38 @@
"animation.tinkatink.cry": {
"animation_length": 1.5,
"bones": {
"neck": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [10, 0, 0],
"1.25": [10, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -2, 0],
"1.25": [0, -2, 0],
"1.5": [0, 0, 0]
}
},
"mouth2": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -5, 0],
"1.25": [0, -5, 0],
"1.5": [0, 0, 0]
}
},
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.25": [0, -3, 0],
"1.25": [0, -3, 0],
"1.5": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
@@ -969,12 +863,60 @@
"1.5": [0, 0, 0]
}
},
"mouth_open_cry": {
"head2": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-15, 0, 0],
"1.25": [-15, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed2": {
"position": {
"0.25": [0, 0, -0.1],
"0.3333": [0, 0, 0],
"1.1667": [0, 0, 0],
"1.25": [0, 0, -0.1]
}
},
"mouth_open2": {
"position": {
"0.0": [0, 0, 0.1],
"0.25": [0, 0, 0],
"1.25": [0, 0, 0],
"1.5": [0, 0, 0.1]
}
},
"head3": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-15, 0, 0],
"1.25": [-15, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_closed3": {
"position": {
"0.25": [0, 0, -0.1],
"0.3333": [0, 0, 0],
"1.1667": [0, 0, 0],
"1.25": [0, 0, -0.1]
}
},
"mouth_open3": {
"position": {
"0.0": [0, 0, 0.1],
"0.25": [0, 0, 0],
"1.25": [0, 0, 0],
"1.5": [0, 0, 0.1]
}
},
"mouth_open": {
"position": {
"0.0833": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.25": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
"0.1667": [0, 0, -0.15],
"1.25": [0, 0, -0.15],
"1.3333": [0, 0, 0]
}
},
"arm_left": {
@@ -1006,38 +948,10 @@
"1.25": [0, 0, -2.4],
"1.5": [0, 0, 0]
}
},
"mouth_closed": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0, -0.5, 0]},
"1.3333": {"pre": [0, -0.5, 0], "post": [0, 0, 0]}
}
},
"mouth_lip_top": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.3333": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"mouth_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.3333": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"mouth_open_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0": {
"0.25": {
"effect": "pokemon.tinkatink.cry"
}
}
@@ -1148,128 +1062,6 @@
"rotation": [0, 0, 32.5]
}
}
},
"animation.tinkatink.ditto_face": {
"loop": true,
"bones": {
"face": {
"position": [0, 0, 0.1],
"scale": 0
},
"face_ditto": {
"position": [0, 0, -0.1]
}
}
},
"animation.tinkatink.happy": {
"loop": true,
"bones": {
"brow_left": {
"position": [0, 0, 0.1]
},
"brow_right": {
"position": [0, 0, 0.1]
},
"eye_left": {
"position": [0, 0, 0.1]
},
"eye_right": {
"position": [0, 0, 0.1]
},
"mouth_closed": {
"position": [0, 0, 0.1]
},
"mouth_lip_top": {
"position": [0, 0, 0.1]
},
"mouth_open_happy": {
"position": [0, 0, -0.1]
},
"eyelid_happy_left": {
"position": [0, 0, -0.1]
},
"eyelid_happy_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.tinkatink.angry": {
"loop": true,
"bones": {
"eye_emote_left": {
"scale": [1, 0.5, 1]
},
"eye_emote_right": {
"scale": [1, 0.5, 1]
},
"eye_emote_left2": {
"position": [0.25, 0, 0],
"scale": [0.5, 1, 1]
},
"eye_emote_right2": {
"position": [-0.25, 0, 0],
"scale": [0.5, 1, 1]
}
}
},
"animation.tinkatink.very_sad": {
"loop": true,
"bones": {
"eye_emote_left": {
"scale": [1, 0.5, 1]
},
"eye_emote_right": {
"scale": [1, 0.5, 1]
},
"eye_emote_left2": {
"position": [-0.25, 0, 0],
"scale": [0.5, 1, 1]
},
"eye_emote_right2": {
"position": [0.25, 0, 0],
"scale": [0.5, 1, 1]
}
}
},
"animation.tinkatink.hurt": {
"loop": true,
"bones": {
"brow_left": {
"position": [0, 0, 0.1]
},
"brow_right": {
"position": [0, 0, 0.1]
},
"eye_left": {
"position": [0, 0, 0.1]
},
"eye_right": {
"position": [0, 0, 0.1]
},
"eyelid_hurt_left": {
"position": [0, 0, -0.1]
},
"eyelid_hurt_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.tinkatink.disinterested": {
"loop": true,
"bones": {
"eye_emote_left": {
"scale": [1, 0.5, 1]
},
"eye_emote_right": {
"scale": [1, 0.5, 1]
},
"eye_emote_left2": {
"position": [0, 0, 0.1]
},
"eye_emote_right2": {
"position": [0, 0, 0.1]
}
}
}
}
}
@@ -4,6 +4,12 @@
"animation.tinkatuff.ground_idle": {
"loop": true,
"bones": {
"tail": {
"rotation": [12.5, 0, 0]
},
"tail2": {
"rotation": [12.5, 0, 0]
},
"arm_right": {
"rotation": [55.98303, 0.22836, "-40.7651+Math.cos((query.anim_time) * 90 * 2 - 120) * 1"],
"position": [-0.25, -0.5, 0]
@@ -15,8 +21,7 @@
"rotation": [0, 0, -5]
},
"finger_right2": {
"rotation": [0, -17.5, 37.5],
"position": [-0.25, 0, 0]
"rotation": [0, -10, 37.5]
},
"arm_left": {
"rotation": [-84.39003, 4.58778, "53.5046+Math.cos((query.anim_time) * 90 * 2 - 120) * 1"]
@@ -25,11 +30,17 @@
"rotation": [0, -15, 55]
},
"finger_left": {
"rotation": [0, 0, -40]
"rotation": [0, 0, -25]
},
"finger_left2": {
"rotation": [20, 0, 0]
},
"hand_left": {
"rotation": [0, 17.5, 0]
},
"hand_right": {
"rotation": [0, -17.5, 0]
},
"leg_left": {
"rotation": [0, -12.5, -5]
},
@@ -37,7 +48,7 @@
"rotation": [0, 12.5, 5]
},
"finger_left3": {
"rotation": [0, 0, 67.5]
"rotation": [0, 0, 57.5]
},
"finger_right3": {
"rotation": [0, 0, -20]
@@ -67,6 +78,9 @@
"head": {
"rotation": ["12.5+Math.cos((query.anim_time) * 90 * 2 - 50) * 2", 0, 0]
},
"mouth_closed": {
"position": [0, 0, 0]
},
"ponytail": {
"rotation": ["0+Math.cos((query.anim_time) * 90 * 2 - 120) * 1", 0, 0]
},
@@ -173,24 +187,10 @@
}
},
"finger_right2": {
"rotation": [7.5, 0, 42.5],
"position": [-0.25, 0.25, 0]
"rotation": [7.5, 0, 10]
},
"finger_right3": {
"rotation": [-0.88045, -9.96156, 5.07673]
},
"finger_left": {
"rotation": [0, 0, -55],
"position": [0, 0.5, 0]
},
"finger_left2": {
"rotation": [0, 0, -17.5]
},
"finger_left3": {
"rotation": [0, 0, 22.5]
},
"finger_right": {
"rotation": [0, 0, 20]
}
}
},
@@ -210,7 +210,7 @@
"rotation": [-15, -2.5, 62.5]
},
"finger_left3": {
"rotation": [0, 0, 22.5]
"rotation": [0, 0, 52.5]
},
"arm_right": {
"rotation": [22.5, -10, -35],
@@ -299,29 +299,18 @@
},
"arm_hammer_right2": {
"rotation": [0, -70, 0]
},
"finger_left": {
"rotation": [0, 0, -52.5],
"position": [0, 0.75, 0]
},
"finger_left2": {
"rotation": [0, 0, -15]
},
"finger_right": {
"rotation": [0, 0, 20]
},
"finger_right2": {
"rotation": [7.5, 0, 37.5],
"position": [-0.25, 0.25, 0]
},
"finger_right3": {
"rotation": [0, 0, -32.5]
}
}
},
"animation.tinkatuff.battle_idle": {
"loop": true,
"bones": {
"tail": {
"rotation": [12.5, 0, 0]
},
"tail2": {
"rotation": [12.5, 0, 0]
},
"arm_right": {
"rotation": [40.98303, 0.22836, "-45.7651+Math.cos((query.anim_time) * 90 * 2 - 40) * 2"]
},
@@ -329,8 +318,7 @@
"rotation": [0, -52.5, 0]
},
"finger_right": {
"rotation": [0, 0, 37.5],
"position": [0, 0.25, 0]
"rotation": [0, 0, -5]
},
"finger_right2": {
"rotation": [0, 0, 37.5]
@@ -342,12 +330,17 @@
"rotation": [0, 0, "55+Math.cos((query.anim_time) * 90 * 2 - 40) * -2"]
},
"finger_left": {
"rotation": [0, 0, -47.5],
"position": [0, 0.5, 0]
"rotation": [0, 0, -25]
},
"finger_left2": {
"rotation": [20, 0, 0]
},
"hand_left": {
"rotation": [0, 17.5, 0]
},
"hand_right": {
"rotation": [0, -17.5, 0]
},
"leg_left": {
"rotation": ["-11.2025+Math.cos((query.anim_time) * 90 * 2) * 3", -21.49336, -9.33448]
},
@@ -355,11 +348,10 @@
"rotation": ["-13.5954+Math.cos((query.anim_time) * 90 * 2) * 3", 22.38126, 10.45107]
},
"finger_left3": {
"rotation": [0, 0, 42.5],
"position": [-0.5, -0.25, 0]
"rotation": [0, 0, 57.5]
},
"finger_right3": {
"rotation": [0, 0, -40]
"rotation": [0, 0, -20]
},
"hammer": {
"rotation": [-12.18122, -2.58318, 113.79667]
@@ -424,8 +416,7 @@
"position": [-0.5, 0, 0]
},
"hammer": {
"rotation": [15, 0, 0],
"position": [0, 0.5, 3.75]
"rotation": [15, 0, 0]
},
"hammer2": {
"rotation": ["90+Math.cos((query.anim_time) * 90 * 1) * -1", 0, 0],
@@ -465,18 +456,43 @@
},
"leg_right": {
"rotation": [-90, 20, 0]
},
"eyes_ditto": {
"position": [0, 0, 0.1]
},
"eyes_blink_ditto": {
"position": [0, 0, -0.1]
}
}
},
"animation.tinkatuff.faint": {
"animation_length": 3,
"bones": {
"arm_right": {
"rotation": {
"0.0": [40.98303, 0.22836, -45.7651],
"0.2083": [5.98, 0.23, -45.77],
"0.2917": [35.98, 0.23, -45.77],
"0.75": [18.48, 5.23, -23.27],
"0.9167": [60.98, -12.27, -35.77],
"1.2083": [30.98, -59.77, -35.77],
"1.3333": [32.05, -62.98, -35.77],
"1.5": [33.48, -67.27, -35.77],
"1.8333": [15.98, -79.77, -35.77],
"1.9167": [67.65, -129.77, -110.77],
"1.9583": [93.48, -154.77, -148.27],
"2.0833": [93.48, -174.77, -168.27],
"2.3333": [93.48, -169.77, -168.27]
}
},
"arm_right2": {
"rotation": {
"0.0": [0, -52.5, 0],
"1.0": [0, -52.5, 0],
"1.2083": [0, -57.5, 0],
"1.5": [0, -30, 0]
}
},
"finger_right": {
"rotation": [0, 0, -5]
},
"finger_right2": {
"rotation": [0, 0, 37.5]
},
"arm_left": {
"rotation": {
"0.0": [-84.39003, 24.58778, 53.5046],
@@ -531,9 +547,30 @@
"2.375": [-30.37, 0, -5]
}
},
"leg_right": {
"rotation": {
"0.0": [-13.6, 22.38, 10.45],
"0.1667": [-31.1, 22.38, 10.45],
"0.25": [-26.1, 22.38, 10.45],
"0.5": [-3.6, 22.38, 10.45],
"0.7917": [6.4, 22.38, 10.45],
"0.9167": [-31.1, 22.38, 10.45],
"1.2083": [-31.1, 42.38, 10.45],
"1.375": [-30, 0, 0],
"1.6667": [-30, 0, 5],
"1.875": [70, 0, 5],
"2.0417": [40.36, 0, 5],
"2.1667": [-30, 0, 5],
"2.25": [-45, 0, 5],
"2.375": [-35, 0, 5]
}
},
"finger_left3": {
"rotation": [0, 0, 57.5]
},
"finger_right3": {
"rotation": [0, 0, -20]
},
"hammer": {
"rotation": {
"0.0": [-0.78, -6.26, 38.97],
@@ -556,6 +593,9 @@
"skirt_left": {
"rotation": [0, 0, -15]
},
"skirt_right": {
"rotation": [-10, 0, 15]
},
"leg_left2": {
"rotation": {
"0.0": [20, 0, 0],
@@ -571,6 +611,18 @@
"2.0417": [15, 0, 0]
}
},
"leg_right2": {
"rotation": {
"0.0": [15, 0, -10],
"0.1667": [35, 0, -10],
"0.25": [-10, 0, -10],
"0.5": [27.5, 0, 5],
"0.7917": [5, 0, 5],
"0.9167": [35, 0, 5],
"1.375": [35, 0, 0],
"1.6667": [22.5, 0, 0]
}
},
"body": {
"rotation": {
"0.9167": [0, 0, 0],
@@ -799,517 +851,132 @@
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.4167": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"1.7917": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
}
},
"mouth_top": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0.5, 0]
},
"0.9167": {
"pre": [0, 0.5, 0],
"post": [0, 0, 0]
},
"1.2917": {
"pre": [0, 0, 0],
"post": [0, 0.5, 0]
},
"2.0417": {
"pre": [0, 0.5, 0],
"post": [0, 0, 0]
}
"0.2083": [0, 0, 0],
"0.25": [0, 0, -0.15],
"0.375": [0, 0, -0.15],
"0.4167": [0, 0, 0],
"0.9167": [0, 0, 0],
"0.9583": [0, 0, -0.15],
"1.75": [0, 0, -0.15],
"1.7917": [0, 0, 0],
"2.0": [0, 0, 0],
"2.0417": [0, 0, -0.15]
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.4167": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"1.7917": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
"0.2083": [0, 0, 0],
"0.25": [0, 0, -0.15],
"0.375": [0, 0, -0.15],
"0.4167": [0, 0, 0],
"0.9167": [0, 0, 0],
"0.9583": [0, 0, -0.15],
"1.75": [0, 0, -0.15],
"1.7917": [0, 0, 0],
"2.0": [0, 0, 0],
"2.0417": [0, 0, -0.15]
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.9167": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"1.2917": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"2.0417": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
}
"0.2083": [0, 0, 0],
"0.25": [0, 0, -0.15],
"0.875": [0, 0, -0.15],
"0.9167": [0, 0, 0],
"1.25": [0, 0, 0],
"1.2917": [0, 0, -0.15],
"2.0": [0, 0, -0.15],
"2.0417": [0, 0, 0]
}
},
"arm_right": {
"rotation": {
"0.0": [40.98303, 0.22836, -45.7651],
"0.2083": [5.98, 0.23, -45.77],
"0.2917": [35.98, 0.23, -45.77],
"0.75": [18.48, 5.23, -23.27],
"0.9167": [60.98, -12.27, -35.77],
"1.2083": [30.98, -59.77, -35.77],
"1.3333": [32.05, -62.98, -35.77],
"1.5": [33.48, -67.27, -35.77],
"1.8333": [15.98, -79.77, -35.77],
"1.9167": [67.65, -129.77, -110.77],
"1.9583": [93.48, -154.77, -148.27],
"2.0833": [93.48, -174.77, -168.27],
"2.3333": [93.48, -169.77, -168.27]
}
},
"arm_right2": {
"rotation": {
"0.0": [0, -52.5, 0],
"1.0": [0, -52.5, 0],
"1.2083": [0, -57.5, 0],
"1.5": [0, -30, 0]
}
},
"finger_right": {
"rotation": [0, 0, -5]
},
"finger_right2": {
"rotation": [0, 0, 37.5]
},
"finger_right3": {
"rotation": [0, 0, -20]
},
"skirt_right": {
"rotation": [-10, 0, 15]
},
"leg_right": {
"rotation": {
"0.0": [-13.6, 22.38, 10.45],
"0.1667": [-31.1, 22.38, 10.45],
"0.25": [-26.1, 22.38, 10.45],
"0.5": [-3.6, 22.38, 10.45],
"0.7917": [6.4, 22.38, 10.45],
"0.9167": [-31.1, 22.38, 10.45],
"1.2083": [-31.1, 42.38, 10.45],
"1.375": [-30, 0, 0],
"1.6667": [-30, 0, 5],
"1.875": [70, 0, 5],
"2.0417": [40.36, 0, 5],
"2.1667": [-30, 0, 5],
"2.25": [-45, 0, 5],
"2.375": [-35, 0, 5]
}
},
"leg_right2": {
"rotation": {
"0.0": [15, 0, -10],
"0.1667": [35, 0, -10],
"0.25": [-10, 0, -10],
"0.5": [27.5, 0, 5],
"0.7917": [5, 0, 5],
"0.9167": [35, 0, 5],
"1.375": [35, 0, 0],
"1.6667": [22.5, 0, 0]
}
},
"brow_left": {
"mouth_closed": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.4167": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
"0.2083": [0, 0, 0],
"0.25": [0, 0, 0.1],
"0.875": [0, 0, 0.1],
"0.9167": [0, 0, 0],
"1.25": [0, 0, 0],
"1.2917": [0, 0, 0.1],
"2.0": [0, 0, 0.1],
"2.0417": [0, 0, 0]
}
},
"brow_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.4167": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
}
},
"mouth_bottom": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, -0.5, 0]
},
"0.9167": {
"pre": [0, -0.5, 0],
"post": [0, 0, 0]
},
"1.2917": {
"pre": [0, 0, 0],
"post": [0, -0.5, 0]
},
"2.0417": {
"pre": [0, -0.5, 0],
"post": [0, 0, 0]
}
}
},
"eye_emote_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.4167": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
}
},
"eye_emote_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.4167": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
}
},
"eyes_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.4167": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
}
},
"eyes_blink_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.4167": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"0.9583": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"1.7917": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
}
},
"mouth_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.9167": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"1.2917": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"2.0417": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"mouth_open_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.9167": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"1.2917": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"2.0417": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
}
}
}
}
},
"animation.tinkatuff.cry": {
"animation_length": 1.5,
"bones": {
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.25": [-15, 0, 0],
"1.25": [-15, 0, 0],
"1.5": [0, 0, 0]
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"mouth_top": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0.5, 0]},
"1.3333": {"pre": [0, 0.5, 0], "post": [0, 0, 0]}
}
},
"mouth_bottom": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, -0.5, 0]},
"1.3333": {"pre": [0, -0.5, 0], "post": [0, 0, 0]}
}
},
"mouth_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.3333": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"mouth_open_ditto": {
"position": {
"0.0": [0, 0, 0],
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.tinkatuff.cry"
}
}
},
"animation.tinkatuff.blink": {
"animation_length": 0.1667,
"animation_length": 0.16667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
}
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
}
}
},
"brow_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"brow_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"eye_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
}
}
},
"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]
}
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.tinkatuff.ditto_face": {
"loop": true,
"animation.tinkatuff.cry": {
"animation_length": 0.91667,
"bones": {
"face": {
"position": [0, 0, 0.1],
"scale": 0
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"face_ditto": {
"position": [0, 0, -0.1]
"mouth_closed": {
"position": {
"0.25": [0, 0, 0],
"0.3333": [0, 0, 0.1],
"0.5833": [0, 0, 0.1],
"0.6667": [0, 0, 0]
}
},
"mouth_open": {
"position": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [0, 0, -0.1],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [0, 0, -0.1],
"lerp_mode": "catmullrom"
},
"0.9167": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.1667": {
"effect": "pokemon.tinkatuff.cry"
}
}
}
@@ -90,7 +90,7 @@
"parent": "chest",
"pivot": [0, 17, -5],
"cubes": [
{"origin": [-2.25, 16, -7.5], "size": [5, 5, 5], "uv": [22, 0]},
{"origin": [-2.75, 16, -7.5], "size": [5.5, 5, 5], "uv": [22, 0]},
{"origin": [0, 18, -2.5], "size": [0, 4, 2], "uv": [30, 37]}
]
},
@@ -486,7 +486,7 @@
"parent": "eye_left",
"pivot": [4.2, 34.1, -10.53],
"cubes": [
{"origin": [4.98, 34.01, -10.53], "size": [3, 1, 1], "inflate": 0.01, "uv": [132, 116]}
{"origin": [4.98, 33.99, -10.53], "size": [3, 1, 1], "inflate": 0.01, "uv": [132, 116]}
]
},
{
@@ -782,7 +782,7 @@
"parent": "eye_right",
"pivot": [-4.2, 34.1, -10.53],
"cubes": [
{"origin": [-7.98, 34.01, -10.53], "size": [3, 1, 1], "inflate": 0.01, "uv": [140, 116]}
{"origin": [-7.98, 33.99, -10.53], "size": [3, 1, 1], "inflate": 0.01, "uv": [140, 116]}
]
},
{
@@ -15,58 +15,18 @@
"name": "tinkatink",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "tinkatink",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "tinkatink",
"pivot": [0, 14, 0],
"locators": {
"top": [0, 14, 0]
}
},
{
"name": "locator_special",
"parent": "tinkatink",
"pivot": [0, 6, -7],
"locators": {
"special": [0, 6, -7]
}
},
{
"name": "body",
"parent": "tinkatink",
"pivot": [0, 3.75, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 6, -6],
"locators": {
"target": [0, 6, -6]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 6, 0],
"locators": {
"middle": [0, 6, 0]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 2.5, -0.25],
"pivot": [0, 1.75, -0.25],
"cubes": [
{"origin": [-1.5, 2, -1.5], "size": [3, 3, 3], "uv": [30, 6]},
{"origin": [-1, 1.5, -2.5], "size": [2, 2, 1], "pivot": [0, 2.5, -2], "rotation": [0, 0, 45], "uv": [47, 12]}
{"origin": [-2, 1.5, -2], "size": [4, 3, 4], "uv": [0, 12]},
{"origin": [-1, 2, -2.75], "size": [2, 2, 1], "pivot": [0, 3, -2.25], "rotation": [0, 0, 45], "uv": [12, 12]}
]
},
{
@@ -74,509 +34,199 @@
"parent": "torso",
"pivot": [0, 4.25, -0.25],
"cubes": [
{"origin": [-4, 4.25, -3.75], "size": [8, 7, 7], "uv": [0, 0]}
]
},
{
"name": "locator_item_hat",
"parent": "head",
"pivot": [0, 12.25, -0.25],
"locators": {
"item_hat": [0, 12.25, -0.25]
}
},
{
"name": "locator_head",
"parent": "head",
"pivot": [0, 11.25, -3.25],
"locators": {
"head": [0, 11.25, -3.25]
}
},
{
"name": "locator_mouth",
"parent": "head",
"pivot": [0, 5.7, -3.75],
"locators": {
"mouth": [0, 5.7, -3.75]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 8.25, -3.75],
"locators": {
"item_face": [0, 8.25, -3.75]
}
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 7.25, -3.75],
"locators": {
"face": [0, 7.25, -3.75]
}
},
{
"name": "face_ditto",
"parent": "head",
"pivot": [0, 7, -3.65]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 7.75, -3.67],
"cubes": [
{"origin": [-3, 7.25, -3.67], "size": [6, 1, 0], "uv": [51, 23]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 7.75, -3.57],
"cubes": [
{"origin": [-3.5, 7.25, -3.57], "size": [7, 1, 0], "uv": [49, 27]},
{"origin": [-3, 7.75, -3.58], "size": [6, 1, 0], "uv": [51, 21]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 6, -3.65],
"cubes": [
{"origin": [-2.5, 5.25, -3.66], "size": [5, 1, 0], "uv": [53, 19]},
{"origin": [-3.5, 5.75, -3.66], "size": [7, 1, 0], "uv": [49, 25]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 5.75, -3.56],
"cubes": [
{"origin": [-3.5, 4.75, -3.56], "size": [7, 2, 0], "uv": [49, 29]}
]
},
{
"name": "face",
"parent": "head",
"pivot": [0, 6.75, -3.75]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 6.75, -3.26]
},
{
"name": "brow_left",
"parent": "eyes",
"pivot": [2.25, 8.5, -3.25],
"cubes": [
{"origin": [1.75, 8, -3.75], "size": [1, 1, 1], "inflate": 0.01, "pivot": [2.25, 8.5, -3.25], "rotation": [0, 0, 5], "uv": [32, 29]}
]
},
{
"name": "brow_right",
"parent": "eyes",
"pivot": [-2.25, 8.5, -3.25],
"cubes": [
{"origin": [-2.75, 8, -3.75], "size": [1, 1, 1], "inflate": 0.01, "pivot": [-2.25, 8.5, -3.25], "rotation": [0, 0, -5], "uv": [32, 25]}
]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.5, 7.75, -3.26],
"cubes": [
{"origin": [2, 6.75, -3.75], "size": [1, 1, 1], "inflate": 0.01, "uv": [28, 29]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2.5, 7.7, -3.75],
"locators": {
"eye2": [2.5, 7.7, -3.75]
}
},
{
"name": "eye_emote_left",
"parent": "eye_left",
"pivot": [2.5, 7.75, -3.75],
"cubes": [
{"origin": [2, 7.75, -3.75], "size": [1, 1, 1], "inflate": 0.025, "uv": [24, 29]}
]
},
{
"name": "eye_emote_left2",
"parent": "eye_left",
"pivot": [2.5, 7.75, -3.75],
"cubes": [
{"origin": [2, 7.75, -3.75], "size": [1, 1, 1], "inflate": 0.02, "uv": [20, 29]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.5, 7.75, -3.26],
"cubes": [
{"origin": [-3, 6.75, -3.75], "size": [1, 1, 1], "inflate": 0.01, "uv": [28, 25]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2.5, 7.7, -3.75],
"locators": {
"eye1": [-2.5, 7.7, -3.75]
}
},
{
"name": "eye_emote_right",
"parent": "eye_right",
"pivot": [-2.5, 7.75, -3.75],
"cubes": [
{"origin": [-3, 7.75, -3.75], "size": [1, 1, 1], "inflate": 0.025, "uv": [24, 25]}
]
},
{
"name": "eye_emote_right2",
"parent": "eye_right",
"pivot": [-2.5, 7.75, -3.75],
"cubes": [
{"origin": [-3, 7.75, -3.75], "size": [1, 1, 1], "inflate": 0.02, "uv": [20, 25]}
]
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [2.5, 7.75, -3.16],
"cubes": [
{"origin": [1.5, 6.75, -3.65], "size": [2, 2, 1], "inflate": 0.03, "uv": [0, 28]}
]
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-2.5, 7.75, -3.16],
"cubes": [
{"origin": [-3.5, 6.75, -3.65], "size": [2, 2, 1], "inflate": 0.03, "uv": [0, 24]}
]
},
{
"name": "eyelid_happy_left",
"parent": "eyes",
"pivot": [2.5, 7.75, -3.16],
"cubes": [
{"origin": [1, 6.75, -3.66], "size": [3, 2, 1], "uv": [12, 28]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eyes",
"pivot": [-2.5, 7.75, -3.16],
"cubes": [
{"origin": [-4, 6.75, -3.66], "size": [3, 2, 1], "uv": [12, 24]}
]
},
{
"name": "eyelid_hurt_left",
"parent": "eyes",
"pivot": [2.5, 7.75, -3.16],
"cubes": [
{"origin": [1.5, 6.75, -3.65], "size": [2, 2, 1], "inflate": 0.03, "uv": [6, 28]}
]
},
{
"name": "eyelid_hurt_right",
"parent": "eyes",
"pivot": [-2.5, 7.75, -3.16],
"cubes": [
{"origin": [-3.5, 6.75, -3.65], "size": [2, 2, 1], "inflate": 0.03, "uv": [6, 24]}
]
},
{
"name": "mouths",
"parent": "face",
"pivot": [0, 4.25, -0.75]
},
{
"name": "mouth_closed",
"parent": "mouths",
"pivot": [0, 5.75, -3.25],
"cubes": [
{"origin": [-1.5, 4.75, -3.76], "size": [3, 1, 1], "inflate": 0.02, "uv": [38, 13]},
{"origin": [-0.5, 5.25, -3.76], "size": [1, 1, 1], "inflate": 0.04, "uv": [46, 16]}
]
},
{
"name": "mouth_lip_top",
"parent": "mouth_closed",
"pivot": [0, 6.25, -3.25],
"cubes": [
{"origin": [-1, 5.75, -3.77], "size": [2, 1, 1], "uv": [39, 16]},
{"origin": [-2, 5.25, -3.76], "size": [4, 1, 1], "uv": [29, 22]}
]
},
{
"name": "mouth_open_cry",
"parent": "mouths",
"pivot": [0.4, 4.25, -1.75],
"cubes": [
{"origin": [-2, 4.75, -3.65], "size": [4, 2, 1], "inflate": 0.01, "uv": [29, 19]}
]
},
{
"name": "mouth_open_happy",
"parent": "mouths",
"pivot": [0.4, 4.25, -1.75],
"cubes": [
{"origin": [-2, 4.75, -3.65], "size": [4, 2, 1], "inflate": 0.01, "uv": [40, 19]},
{"origin": [-1.5, 4.75, -3.65], "size": [3, 1, 1], "inflate": 0.02, "uv": [40, 22]},
{"origin": [-0.5, 5.4, -3.65], "size": [1, 1, 1], "inflate": 0.03, "uv": [42, 7]}
]
},
{
"name": "hair_main",
"parent": "head",
"pivot": [0, 10.75, -0.75]
},
{
"name": "hair",
"parent": "hair_main",
"pivot": [0, 10.75, -0.75],
"rotation": [12.5, 0, 0],
"cubes": [
{"origin": [-0.5, 10.25, -1.75], "size": [1, 2, 1], "uv": [25, 15]}
]
},
{
"name": "hair2",
"parent": "hair",
"pivot": [1, 12.25, -0.75],
"rotation": [35, 0, 0],
"cubes": [
{"origin": [-1, 12.25, -2.25], "size": [2, 3, 2], "inflate": 0.01, "uv": [30, 13]}
{"origin": [-3.5, 4.25, -3.25], "size": [7, 6, 6], "uv": [0, 0]}
]
},
{
"name": "hair3",
"parent": "hair_main",
"pivot": [0, 11.25, -0.75],
"rotation": [-2.5, 0, 0],
"parent": "head",
"pivot": [0, 10.25, -0.25],
"rotation": [-5, 0, 0],
"cubes": [
{"origin": [-2.5, 11.25, -3.75], "size": [5, 0, 3], "uv": [34, 25]}
{"origin": [-2.5, 10.25, -3.25], "size": [5, 0, 3], "uv": [11, 21]}
]
},
{
"name": "hair4",
"parent": "hair3",
"pivot": [0, 11.25, -3.75],
"rotation": [-7.5, 0, 0],
"pivot": [0, 10.25, -3.25],
"rotation": [-15, 0, 0],
"cubes": [
{"origin": [-3, 9.25, -3.75], "size": [6, 2, 0], "uv": [36, 29]},
{"origin": [-0.5, 9.25, -3.75], "size": [1, 2, 0], "inflate": 0.01, "uv": [43, 10]}
{"origin": [-2.5, 8.25, -3.25], "size": [5, 2, 0], "uv": [43, 0]}
]
},
{
"name": "arms",
"parent": "torso",
"pivot": [0, 3.25, 0]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [1.5, 3.25, 0],
"name": "eye_right",
"parent": "head",
"pivot": [-2.75, 6.5, -2.76],
"rotation": [0, 0, -5],
"cubes": [
{"origin": [1.25, 2.25, -1], "size": [2, 2, 2], "uv": [8, 19]}
{"origin": [-2.75, 6, -3.26], "size": [1, 2, 1], "uv": [51, 2]}
]
},
{
"name": "hand_left",
"parent": "arm_left",
"pivot": [3.25, 3.25, 0],
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-0.5, 3.5, -0.15],
"cubes": [
{"origin": [3.25, 2.25, -1.5], "size": [3, 2, 3], "inflate": 0.25, "uv": [12, 14]}
{"origin": [-2.75, 6, -3.16], "size": [1, 2, 1], "inflate": 0.01, "uv": [47, 2]}
]
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [6, 3.25, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [6, 3.25, 0]
}
},
{
"name": "fingers_left",
"parent": "hand_left",
"pivot": [6.5, 3.85, 0]
},
{
"name": "finger_left",
"parent": "fingers_left",
"pivot": [6.5, 3.85, 0],
"name": "eye_left",
"parent": "head",
"pivot": [2.75, 6.5, -2.76],
"rotation": [0, 0, 5],
"cubes": [
{"origin": [6.5, 2.85, -0.5], "size": [1, 1, 1], "inflate": 0.1, "uv": [20, 21]}
{"origin": [1.75, 6, -3.26], "size": [1, 2, 1], "uv": [26, 7]}
]
},
{
"name": "finger_left2",
"parent": "fingers_left",
"pivot": [6.5, 3.85, -0.6],
"rotation": [0, 17.5, 0],
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [0.5, 3.5, -0.15],
"cubes": [
{"origin": [6.5, 2.85, -1.7], "size": [1, 1, 1], "inflate": 0.1, "uv": [16, 21]}
{"origin": [1.75, 6, -3.16], "size": [1, 2, 1], "inflate": 0.01, "uv": [32, 8]}
]
},
{
"name": "finger_left3",
"parent": "fingers_left",
"pivot": [6.5, 3.85, 0.6],
"rotation": [0, -17.5, 0],
"name": "hair",
"parent": "head",
"pivot": [0, 10.25, 0.25],
"rotation": [12.5, 0, 0],
"cubes": [
{"origin": [6.5, 2.85, 0.7], "size": [1, 1, 1], "inflate": 0.1, "uv": [24, 21]}
{"origin": [0, 9.75, -0.75], "size": [0, 2, 1], "uv": [4, 0]}
]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-1.5, 3.25, 0],
"name": "hair2",
"parent": "hair",
"pivot": [0, 11.75, 0.25],
"rotation": [22.5, 0, 0],
"cubes": [
{"origin": [-3.25, 2.25, -1], "size": [2, 2, 2], "uv": [0, 19]}
{"origin": [0, 11.75, -1.75], "size": [0, 3, 2], "inflate": 0.01, "uv": [0, 10]}
]
},
{
"name": "hand_right",
"parent": "arm_right",
"pivot": [-3.25, 3.25, 0],
"name": "mouth_closed",
"parent": "head",
"pivot": [0, 4.25, -0.25],
"cubes": [
{"origin": [-6.25, 2.25, -1.5], "size": [3, 2, 3], "inflate": 0.25, "uv": [0, 14]}
{"origin": [-2.5, 4.75, -3.2575], "size": [5, 2, 0], "inflate": 0.001, "uv": [26, 5]}
]
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-6, 3.25, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-6, 3.25, 0]
}
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-6, 2.25, 0],
"locators": {
"item": [-6, 2.25, 0]
}
},
{
"name": "fingers_right",
"parent": "hand_right",
"pivot": [-6.5, 3.85, 0]
},
{
"name": "finger_right",
"parent": "fingers_right",
"pivot": [-6.5, 3.85, 0],
"name": "mouth_open",
"parent": "head",
"pivot": [-0.1, 4.25, -1.25],
"cubes": [
{"origin": [-7.5, 2.85, -0.5], "size": [1, 1, 1], "inflate": 0.1, "uv": [20, 19]}
]
},
{
"name": "finger_right2",
"parent": "fingers_right",
"pivot": [-6.5, 3.85, -0.6],
"rotation": [0, -17.5, 0],
"cubes": [
{"origin": [-7.5, 2.85, -1.7], "size": [1, 1, 1], "inflate": 0.1, "uv": [16, 19]}
]
},
{
"name": "finger_right3",
"parent": "fingers_right",
"pivot": [-6.5, 3.85, 0.6],
"rotation": [0, 17.5, 0],
"cubes": [
{"origin": [-7.5, 2.85, 0.7], "size": [1, 1, 1], "inflate": 0.1, "uv": [24, 19]}
{"origin": [-1.5, 4.75, -3.1575], "size": [3, 2, 0], "uv": [25, 12]}
]
},
{
"name": "arm_hammer_left",
"parent": "arms",
"pivot": [1.5, 3.25, 0]
"parent": "torso",
"pivot": [2, 3.25, 0]
},
{
"name": "hammer",
"parent": "arm_hammer_left",
"pivot": [7.25, 3, -0.5]
"pivot": [6.75, 3, -0.5]
},
{
"name": "hammer2",
"parent": "hammer",
"pivot": [7.5, 7.41875, -0.525],
"pivot": [6.75, 7.41875, -0.525],
"cubes": [
{"origin": [7, 1.25, -1], "size": [1, 4, 1], "uv": [54, 12]},
{"origin": [7, 1.25, -1], "size": [1, 4, 1], "inflate": 0.1, "uv": [59, 12]}
{"origin": [5.25, 5.25, -2], "size": [3, 6, 3], "uv": [16, 12]},
{"origin": [6.25, 1.75, -1], "size": [1, 4, 1], "uv": [0, 0]},
{"origin": [5.75, 7, -5.65], "size": [2, 0, 2], "pivot": [6.5, 6.4375, -2.575], "rotation": [-90, 0, 0], "uv": [22, 22]},
{"origin": [6.25, 6.925, -5.8], "size": [1, 0, 1], "pivot": [6.5, 6.4375, -2.575], "rotation": [-90, 0, 0], "uv": [23, 21]}
]
},
{
"name": "rattle",
"parent": "hammer2",
"pivot": [7.5, 9.75, -2],
"name": "arm_left",
"parent": "torso",
"pivot": [2, 3.25, 0],
"cubes": [
{"origin": [7, 9.25, -2.5], "size": [1, 1, 1], "inflate": 0.01, "pivot": [7.5, 9.75, -2], "rotation": [0, 0, 45], "uv": [60, 1]},
{"origin": [6.5, 7.25, -2.4], "size": [2, 2, 1], "inflate": 0.11, "pivot": [7.5, 8.25, -1.9], "rotation": [0, 0, 45], "uv": [46, 0]},
{"origin": [5.5, 4.75, -2.5], "size": [4, 7, 4], "uv": [48, 0]}
{"origin": [2, 2.25, -1.5], "size": [4, 2, 3], "uv": [0, 19]}
]
},
{
"name": "locator_physical",
"parent": "rattle",
"pivot": [7.5, 11.75, -0.5],
"locators": {
"physical": [7.5, 11.75, -0.5]
}
"name": "finger_left",
"parent": "arm_left",
"pivot": [6, 3.5, 0],
"cubes": [
{"origin": [6, 2.5, -0.5], "size": [1, 1, 1], "uv": [26, 10]}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [0, 1.5, 0]
"name": "finger_left2",
"parent": "arm_left",
"pivot": [6, 3.5, -0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [6, 2.5, -1.5], "size": [1, 1, 1], "uv": [43, 2]}
]
},
{
"name": "finger_left3",
"parent": "arm_left",
"pivot": [6, 3.5, 0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [6, 2.5, 0.5], "size": [1, 1, 1], "uv": [11, 19]}
]
},
{
"name": "arm_right",
"parent": "torso",
"pivot": [-2, 3.25, 0],
"cubes": [
{"origin": [-6, 2.25, -1.5], "size": [4, 2, 3], "uv": [20, 0]}
]
},
{
"name": "finger_right",
"parent": "arm_right",
"pivot": [-6, 3.5, 0],
"cubes": [
{"origin": [-7, 2.5, -0.5], "size": [1, 1, 1], "uv": [28, 14]}
]
},
{
"name": "finger_right2",
"parent": "arm_right",
"pivot": [-6, 3.5, -0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [-7, 2.5, -1.5], "size": [1, 1, 1], "uv": [56, 9]}
]
},
{
"name": "finger_right3",
"parent": "arm_right",
"pivot": [-6, 3.5, 0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [-7, 2.5, 0.5], "size": [1, 1, 1], "uv": [52, 9]}
]
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [1.25, 1.5, 0],
"parent": "body",
"pivot": [0.75, 1.5, 0],
"cubes": [
{"origin": [-0.25, -0.25, -1.5], "size": [3, 3, 3], "inflate": -0.25, "uv": [35, 0]}
{"origin": [0.25, 0, -2], "size": [2, 2, 4], "inflate": 0.01, "uv": [35, 0]}
]
},
{
"name": "locator_foot_secondary",
"parent": "leg_left",
"pivot": [1.4, 0.5, 0.1],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [1.4, 0.5, 0.1]
}
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-1.25, 1.5, 0],
"parent": "body",
"pivot": [-0.75, 1.5, 0],
"cubes": [
{"origin": [-2.75, -0.25, -1.5], "size": [3, 3, 3], "inflate": -0.25, "uv": [23, 0]}
{"origin": [-2.25, 0, -2], "size": [2, 2, 4], "inflate": 0.01, "uv": [52, 3]}
]
},
{
"name": "locator_foot_primary",
"parent": "leg_right",
"pivot": [-1.4, 0.5, 0.1],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-1.4, 0.5, 0.1]
}
}
]
}
@@ -0,0 +1,233 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.tinkatink_dot",
"texture_width": 64,
"texture_height": 32,
"visible_bounds_width": 2,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "tinkatink",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "tinkatink",
"pivot": [0, 3.75, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 1.75, -0.25],
"cubes": [
{"origin": [-2, 1.5, -2], "size": [4, 3, 4], "uv": [0, 12]},
{"origin": [-1, 2, -2.75], "size": [2, 2, 1], "pivot": [0, 3, -2.25], "rotation": [0, 0, 45], "uv": [12, 12]}
]
},
{
"name": "head",
"parent": "torso",
"pivot": [0, 4.25, -0.25],
"cubes": [
{"origin": [-3.5, 4.25, -3.25], "size": [7, 6, 6], "uv": [0, 0]}
]
},
{
"name": "hair3",
"parent": "head",
"pivot": [0, 10.25, -0.25],
"rotation": [-5, 0, 0],
"cubes": [
{"origin": [-2.5, 10.25, -3.25], "size": [5, 0, 3], "uv": [11, 21]}
]
},
{
"name": "hair4",
"parent": "hair3",
"pivot": [0, 10.25, -3.25],
"rotation": [-15, 0, 0],
"cubes": [
{"origin": [-2.5, 8.25, -3.25], "size": [5, 2, 0], "uv": [43, 0]}
]
},
{
"name": "eye_right",
"parent": "head",
"pivot": [-2.75, 6.5, -2.76],
"rotation": [0, 0, -5],
"cubes": [
{"origin": [-2.75, 6, -3.26], "size": [1, 2, 1], "uv": [51, 2]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-0.5, 3.5, -0.15],
"cubes": [
{"origin": [-2.75, 6, -3.16], "size": [1, 2, 1], "inflate": 0.01, "uv": [47, 2]}
]
},
{
"name": "eye_left",
"parent": "head",
"pivot": [2.75, 6.5, -2.76],
"rotation": [0, 0, 5],
"cubes": [
{"origin": [1.75, 6, -3.26], "size": [1, 2, 1], "uv": [26, 7]}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [0.5, 3.5, -0.15],
"cubes": [
{"origin": [1.75, 6, -3.16], "size": [1, 2, 1], "inflate": 0.01, "uv": [32, 8]}
]
},
{
"name": "hair",
"parent": "head",
"pivot": [0, 10.25, 0.25],
"rotation": [12.5, 0, 0],
"cubes": [
{"origin": [0, 9.75, -0.75], "size": [0, 2, 1], "uv": [4, 0]}
]
},
{
"name": "hair2",
"parent": "hair",
"pivot": [0, 11.75, 0.25],
"rotation": [22.5, 0, 0],
"cubes": [
{"origin": [0, 11.75, -1.75], "size": [0, 3, 2], "inflate": 0.01, "uv": [0, 10]}
]
},
{
"name": "mouth_closed",
"parent": "head",
"pivot": [0, 4.25, -0.25],
"cubes": [
{"origin": [-2.5, 4.75, -3.2575], "size": [5, 2, 0], "inflate": 0.001, "uv": [26, 5]}
]
},
{
"name": "mouth_open",
"parent": "head",
"pivot": [-0.1, 4.25, -1.25],
"cubes": [
{"origin": [-1.5, 4.75, -3.1575], "size": [3, 2, 0], "uv": [25, 12]}
]
},
{
"name": "arm_hammer_left",
"parent": "torso",
"pivot": [2, 3.25, 0]
},
{
"name": "hammer",
"parent": "arm_hammer_left",
"pivot": [6.75, 3, -0.5]
},
{
"name": "hammer2",
"parent": "hammer",
"pivot": [6.75, 7.41875, -0.525],
"cubes": [
{"origin": [5.25, 5.25, -2], "size": [3, 6, 3], "uv": [16, 12]},
{"origin": [6.25, 1.75, -1], "size": [1, 4, 1], "uv": [0, 0]},
{"origin": [5.75, 8.2625, -3.0125], "size": [2, 0, 2], "pivot": [6.75, 8.2625, -2.0125], "rotation": [-90, 0, 45], "uv": [-2, 24]}
]
},
{
"name": "arm_left",
"parent": "torso",
"pivot": [2, 3.25, 0],
"cubes": [
{"origin": [2, 2.25, -1.5], "size": [4, 2, 3], "uv": [0, 19]}
]
},
{
"name": "finger_left",
"parent": "arm_left",
"pivot": [6, 3.5, 0],
"cubes": [
{"origin": [6, 2.5, -0.5], "size": [1, 1, 1], "uv": [26, 10]}
]
},
{
"name": "finger_left2",
"parent": "arm_left",
"pivot": [6, 3.5, -0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [6, 2.5, -1.5], "size": [1, 1, 1], "uv": [43, 2]}
]
},
{
"name": "finger_left3",
"parent": "arm_left",
"pivot": [6, 3.5, 0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [6, 2.5, 0.5], "size": [1, 1, 1], "uv": [11, 19]}
]
},
{
"name": "arm_right",
"parent": "torso",
"pivot": [-2, 3.25, 0],
"cubes": [
{"origin": [-6, 2.25, -1.5], "size": [4, 2, 3], "uv": [20, 0]}
]
},
{
"name": "finger_right",
"parent": "arm_right",
"pivot": [-6, 3.5, 0],
"cubes": [
{"origin": [-7, 2.5, -0.5], "size": [1, 1, 1], "uv": [28, 14]}
]
},
{
"name": "finger_right2",
"parent": "arm_right",
"pivot": [-6, 3.5, -0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [-7, 2.5, -1.5], "size": [1, 1, 1], "uv": [56, 9]}
]
},
{
"name": "finger_right3",
"parent": "arm_right",
"pivot": [-6, 3.5, 0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [-7, 2.5, 0.5], "size": [1, 1, 1], "uv": [52, 9]}
]
},
{
"name": "leg_left",
"parent": "body",
"pivot": [0.75, 1.5, 0],
"cubes": [
{"origin": [0.25, 0, -2], "size": [2, 2, 4], "inflate": 0.01, "uv": [35, 0]}
]
},
{
"name": "leg_right",
"parent": "body",
"pivot": [-0.75, 1.5, 0],
"cubes": [
{"origin": [-2.25, 0, -2], "size": [2, 2, 4], "inflate": 0.01, "uv": [52, 3]}
]
}
]
}
]
}
@@ -4,7 +4,7 @@
{
"description": {
"identifier": "geometry.tinkatuff",
"texture_width": 128,
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
@@ -15,680 +15,289 @@
"name": "tinkatuff",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "tinkatuff",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "tinkatuff",
"pivot": [0, 22, 0],
"locators": {
"top": [0, 22, 0]
}
},
{
"name": "locator_special",
"parent": "tinkatuff",
"pivot": [0, 8, -8],
"locators": {
"special": [0, 8, -8]
}
},
{
"name": "body",
"parent": "tinkatuff",
"pivot": [0, 6.25, 0]
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 8, -6],
"locators": {
"target": [0, 8, -6]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 9, 0],
"locators": {
"middle": [0, 9, 0]
}
"pivot": [0, 6, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 4.5, 0],
"pivot": [0, 4.25, 0],
"cubes": [
{"origin": [-2.5, 3.25, -2], "size": [5, 3, 4], "inflate": 0.25, "uv": [0, 14]},
{"origin": [-2.5, 3.25, -2], "size": [5, 3, 4], "inflate": 0.5, "uv": [18, 14]}
{"origin": [-2, 7.5, -1.5], "size": [4, 3, 3], "uv": [41, 41]},
{"origin": [-2.5, 3, -2], "size": [5, 5, 4], "uv": [36, 0]}
]
},
{
"name": "chest",
"name": "skirt_left",
"parent": "torso",
"pivot": [0, 6, 0],
"pivot": [2.5, 3, 0],
"rotation": [0, 0, 45],
"cubes": [
{"origin": [-2, 5.75, -2], "size": [4, 4, 4], "uv": [24, 0]}
{"origin": [2.5, 3, -1.5], "size": [3, 0, 3], "uv": [6, 15]}
]
},
{
"name": "head",
"parent": "chest",
"pivot": [0, 8.75, 0.5],
"name": "skirt_right",
"parent": "torso",
"pivot": [-2.5, 3, 0],
"rotation": [0, 0, -45],
"cubes": [
{"origin": [-4, 8.75, -4], "size": [8, 6, 8], "uv": [0, 0]}
{"origin": [-5.5, 3, -1.5], "size": [3, 0, 3], "uv": [0, 15]}
]
},
{
"name": "locator_mouth",
"parent": "head",
"pivot": [0, 9.75, -4],
"locators": {
"mouth": [0, 9.75, -4]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 12.25, -4],
"locators": {
"item_face": [0, 12.25, -4]
}
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 11.75, -4],
"locators": {
"face": [0, 11.75, -4]
}
},
{
"name": "face_ditto",
"parent": "head",
"pivot": [0, 11, -3.9]
},
{
"name": "eyes_ditto",
"parent": "face_ditto",
"pivot": [0, 11.75, -3.92],
"cubes": [
{"origin": [-3, 11.25, -3.92], "size": [6, 1, 0], "uv": [22, 49]}
]
},
{
"name": "eyes_blink_ditto",
"parent": "face_ditto",
"pivot": [0, 11.75, -3.82],
"cubes": [
{"origin": [-3.5, 11.25, -3.82], "size": [7, 1, 0], "uv": [21, 51]},
{"origin": [-3, 11.75, -3.83], "size": [6, 1, 0], "uv": [22, 53]}
]
},
{
"name": "mouth_ditto",
"parent": "face_ditto",
"pivot": [0, 10, -3.9],
"cubes": [
{"origin": [-2.5, 9.25, -3.91], "size": [5, 1, 0], "uv": [23, 57]},
{"origin": [-3.5, 9.75, -3.91], "size": [7, 1, 0], "uv": [21, 55]}
]
},
{
"name": "mouth_open_ditto",
"parent": "face_ditto",
"pivot": [0, 9.75, -3.81],
"cubes": [
{"origin": [-3.5, 8.75, -3.81], "size": [7, 2, 0], "uv": [21, 59]}
]
},
{
"name": "face",
"parent": "head",
"pivot": [0, 11.75, -4.01]
},
{
"name": "eyes",
"parent": "face",
"pivot": [0, 12, -3.51]
},
{
"name": "brow_left",
"parent": "eyes",
"pivot": [2.25, 12.75, -3.5],
"cubes": [
{"origin": [1.75, 12.25, -4], "size": [1, 1, 1], "inflate": 0.01, "uv": [16, 52]}
]
},
{
"name": "brow_right",
"parent": "eyes",
"pivot": [-2.25, 12.75, -3.5],
"cubes": [
{"origin": [-2.75, 12.25, -4], "size": [1, 1, 1], "inflate": 0.01, "uv": [11, 52], "mirror": true}
]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [2.5, 12, -3.51],
"cubes": [
{"origin": [2, 11, -4], "size": [1, 1, 1], "inflate": 0.01, "uv": [6, 52]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [2.5, 12, -4],
"locators": {
"eye2": [2.5, 12, -4]
}
},
{
"name": "eye_emote_left",
"parent": "eye_left",
"pivot": [2.5, 12, -4],
"cubes": [
{"origin": [2, 12, -4], "size": [1, 1, 1], "inflate": 0.025, "uv": [6, 49]}
]
},
{
"name": "eye_emote_left2",
"parent": "eye_left",
"pivot": [2.5, 12, -4],
"cubes": [
{"origin": [2, 12, -4], "size": [1, 1, 1], "inflate": 0.02, "uv": [16, 49]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-2.5, 12, -3.51],
"cubes": [
{"origin": [-3, 11, -4], "size": [1, 1, 1], "inflate": 0.01, "uv": [1, 52], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-2.5, 12, -4],
"locators": {
"eye1": [-2.5, 12, -4]
}
},
{
"name": "eye_emote_right",
"parent": "eye_right",
"pivot": [-2.5, 12, -4],
"cubes": [
{"origin": [-3, 12, -4], "size": [1, 1, 1], "inflate": 0.025, "uv": [1, 49], "mirror": true}
]
},
{
"name": "eye_emote_right2",
"parent": "eye_right",
"pivot": [-2.5, 12, -4],
"cubes": [
{"origin": [-3, 12, -4], "size": [1, 1, 1], "inflate": 0.02, "uv": [11, 49], "mirror": true}
]
},
{
"name": "eyelid_left",
"parent": "eyes",
"pivot": [2.5, 12, -3.41],
"cubes": [
{"origin": [1.5, 11, -3.9], "size": [2, 2, 1], "inflate": 0.03, "uv": [8, 45]}
]
},
{
"name": "eyelid_right",
"parent": "eyes",
"pivot": [-2.5, 12, -3.41],
"cubes": [
{"origin": [-3.5, 11, -3.9], "size": [2, 2, 1], "inflate": 0.03, "uv": [1, 45], "mirror": true}
]
},
{
"name": "eyelid_hurt_left",
"parent": "eyes",
"pivot": [2.5, 12, -3.41],
"cubes": [
{"origin": [1.5, 11, -3.9], "size": [2, 2, 1], "inflate": 0.03, "uv": [22, 45]}
]
},
{
"name": "eyelid_hurt_right",
"parent": "eyes",
"pivot": [-2.5, 12, -3.41],
"cubes": [
{"origin": [-3.5, 11, -3.9], "size": [2, 2, 1], "inflate": 0.03, "uv": [15, 45], "mirror": true}
]
},
{
"name": "eyelid_happy_left",
"parent": "eyes",
"pivot": [2.5, 12, -3.41],
"cubes": [
{"origin": [1, 11, -3.91], "size": [3, 2, 1], "uv": [38, 45]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eyes",
"pivot": [-2.5, 12, -3.41],
"cubes": [
{"origin": [-4, 11, -3.91], "size": [3, 2, 1], "uv": [29, 45], "mirror": true}
]
},
{
"name": "mouths",
"parent": "face",
"pivot": [0, 10.25, -3.91],
"cubes": [
{"origin": [-1.5, 9.75, -4], "size": [3, 1, 1], "inflate": 0.01, "uv": [1, 55]}
]
},
{
"name": "mouth_top",
"parent": "mouths",
"pivot": [0, 11.25, -4.01],
"cubes": [
{"origin": [-0.5, 10.27, -4], "size": [1, 1, 1], "inflate": 0.03, "uv": [10, 55]}
]
},
{
"name": "mouth_bottom",
"parent": "mouths",
"pivot": [0, 10.25, -4.01],
"cubes": [
{"origin": [-0.5, 9.23, -4], "size": [1, 1, 1], "inflate": 0.03, "uv": [10, 59]}
]
},
{
"name": "mouth_open",
"parent": "mouths",
"pivot": [0, 10.25, -3.91],
"cubes": [
{"origin": [-1.5, 9.25, -3.9], "size": [3, 2, 1], "inflate": 0.02, "uv": [1, 58]}
]
},
{
"name": "hair",
"parent": "head",
"pivot": [0, 17.25, 0.7],
"rotation": [-10, 0, 0],
"cubes": [
{"origin": [4.5, 10.25, -3.8], "size": [0, 3, 9], "pivot": [4.5, 13.25, 0.7], "rotation": [0, 0, 9], "uv": [49, 47]},
{"origin": [-4.5, 10.25, -3.8], "size": [0, 3, 9], "pivot": [-4.5, 13.25, 0.7], "rotation": [0, 0, -9], "uv": [49, 51], "mirror": true},
{"origin": [-4.5, 13.25, -3.8], "size": [9, 4, 9], "uv": [33, 0]},
{"origin": [-2.5, 10.25, -3.8], "size": [5, 3, 0], "pivot": [0, 13.25, -3.8], "rotation": [13.5, 0, 0], "uv": [53, 48]},
{"origin": [0.5, 10.25, 5.2], "size": [4, 3, 0], "pivot": [4.5, 13.25, 5.2], "rotation": [0, 0, 9], "uv": [49, 52]},
{"origin": [-4.5, 10.25, 5.2], "size": [4, 3, 0], "pivot": [-4.5, 13.25, 5.2], "rotation": [0, 0, -9], "uv": [59, 52], "mirror": true}
]
},
{
"name": "locator_head",
"parent": "hair",
"pivot": [0, 16.25, -3.8],
"locators": {
"head": [0, 16.25, -3.8]
}
},
{
"name": "locator_item_hat",
"parent": "hair",
"pivot": [0, 17.25, 0.7],
"locators": {
"item_hat": [0, 17.25, 0.7]
}
},
{
"name": "hair2",
"parent": "hair",
"pivot": [4.5, 14.25, -0.8],
"rotation": [22.5, -90, 0]
},
{
"name": "hair3",
"parent": "hair2",
"pivot": [4.5, 14.25, -0.8],
"cubes": [
{"origin": [2.5, 14.25, -0.8], "size": [4, 7, 0], "uv": [40, 56]}
]
},
{
"name": "ponytail",
"parent": "hair",
"pivot": [0, 16.25, 1.2],
"rotation": [-20, 0, 0],
"cubes": [
{"origin": [-4, 15.25, 0.2], "size": [8, 7, 7], "uv": [37, 13]}
]
},
{
"name": "ponytail2",
"parent": "ponytail",
"pivot": [0, 18.25, 6.7],
"rotation": [-22.5, 0, 0],
"cubes": [
{"origin": [-3, 15.75, 5.2], "size": [6, 5, 7], "uv": [39, 27]}
]
},
{
"name": "ponytail3",
"parent": "ponytail2",
"pivot": [0, 17.75, 11.2],
"rotation": [52.5, 0, 0],
"cubes": [
{"origin": [-1.5, 16.25, 10.7], "size": [3, 3, 5], "uv": [60, 0]}
]
},
{
"name": "arms",
"parent": "chest",
"pivot": [0, 7.5, 0]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [2, 7.5, 0],
"parent": "torso",
"pivot": [2, 8, 0],
"cubes": [
{"origin": [1, 6.5, -1.5], "size": [4, 2, 3], "uv": [14, 28]}
{"origin": [1, 7, -1], "size": [4, 2, 2], "uv": [35, 47]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [5, 8.5, 1],
"pivot": [5, 9, 1],
"cubes": [
{"origin": [5, 6, -2], "size": [4, 3, 4], "inflate": 0.001, "uv": [16, 21]}
{"origin": [5, 7, -1.5], "size": [4, 2, 3], "inflate": 0.001, "uv": [44, 35]}
]
},
{
"name": "locator_hand_secondary",
"parent": "arm_left2",
"pivot": [8.5, 7.45, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [8.5, 7.45, 0]
}
},
{
"name": "fingers_left",
"parent": "arm_left2",
"pivot": [9, 7.25, -0.5]
},
{
"name": "finger_left",
"parent": "fingers_left",
"pivot": [9, 7.75, -0.75],
"parent": "arm_left2",
"pivot": [9, 7.75, -0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [9, 7.75, -1.75], "size": [1, 1, 1], "inflate": 0.25, "uv": [0, 23]}
{"origin": [9, 7.75, -1.5], "size": [1, 1, 1], "uv": [33, 44]}
]
},
{
"name": "finger_left2",
"parent": "fingers_left",
"pivot": [9, 7.75, 0.75],
"parent": "arm_left2",
"pivot": [9, 7.75, 0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [9, 7.75, 0.75], "size": [1, 1, 1], "inflate": 0.25, "uv": [12, 23]}
{"origin": [9, 7.75, 0.5], "size": [1, 1, 1], "uv": [40, 30]}
]
},
{
"name": "finger_left3",
"parent": "fingers_left",
"pivot": [9, 7.25, 0],
"parent": "arm_left2",
"pivot": [9, 8, 0],
"cubes": [
{"origin": [9, 6.25, -0.5], "size": [1, 1, 1], "inflate": 0.25, "uv": [16, 23]}
{"origin": [9, 7, -0.5], "size": [1, 1, 1], "uv": [36, 30]}
]
},
{
"name": "arm_hammer_right",
"parent": "torso",
"pivot": [-2, 8, 0]
},
{
"name": "arm_hammer_right2",
"parent": "arm_hammer_right",
"pivot": [-5, 9, 1]
},
{
"name": "hammer",
"parent": "arm_hammer_right2",
"pivot": [-9.75, 8, 0]
},
{
"name": "hammer2",
"parent": "hammer",
"pivot": [-9.55, 7.9675, -9.0675],
"cubes": [
{"origin": [-11, 6.5, -20], "size": [3, 3, 6], "uv": [30, 9]},
{"origin": [-10.5, 6.475, -18.25], "size": [2, 0, 2], "uv": [-1, 54]},
{"origin": [-10, 6.4, -18.4], "size": [1, 0, 1], "uv": [-1, 54]},
{"origin": [-11, 6.5, -12.5], "size": [3, 3, 3], "uv": [0, 47]},
{"origin": [-10, 7.5, -14.5], "size": [1, 1, 18], "inflate": 0.001, "uv": [0, 0]},
{"origin": [-15.5, 4.025, -18.525], "size": [12, 11, 0], "pivot": [-9.5, 9.525, -18.525], "rotation": [-90, -180, 0], "uv": [0, 36]},
{"origin": [-15.5, 3.5, -30.5], "size": [0, 8, 5], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [34, 31]},
{"origin": [-15.5, 3.5, -30.5], "size": [3, 8, 0], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [47, 47]},
{"origin": [-7.5, 2.5, -30.5], "size": [4, 9, 0], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [12, 47]},
{"origin": [-3.5, 2.525, -20.025], "size": [0, 9, 5], "pivot": [-3.5, 7.025, -17.525], "rotation": [90, 180, 0], "uv": [24, 31]},
{"origin": [-13.5, 12.5, -29.5], "size": [8, 1, 0], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [0, 7]},
{"origin": [-13.5, 7.525, -26.025], "size": [8, 0, 4], "pivot": [-9.5, 7.525, -24.025], "rotation": [90, 180, 0], "uv": [17, 19]}
]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-2, 7.5, 0],
"parent": "torso",
"pivot": [-2, 8, 0],
"cubes": [
{"origin": [-5, 6.5, -1.5], "size": [4, 2, 3], "uv": [0, 28], "mirror": true}
{"origin": [-5, 7, -1], "size": [4, 2, 2], "uv": [0, 32]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-5, 8.5, 1.5],
"pivot": [-5, 9, 1],
"cubes": [
{"origin": [-9, 6, -2], "size": [4, 3, 4], "inflate": 0.001, "uv": [0, 21], "mirror": true}
{"origin": [-9, 7, -1.5], "size": [4, 2, 3], "inflate": 0.001, "uv": [44, 30]}
]
},
{
"name": "locator_hand_primary",
"parent": "arm_right2",
"pivot": [-8.5, 7.45, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-8.5, 7.45, 0]
}
},
{
"name": "fingers_right",
"parent": "arm_right2",
"pivot": [-9, 7.25, -0.5]
},
{
"name": "finger_right",
"parent": "fingers_right",
"pivot": [-9, 7.75, -0.75],
"parent": "arm_right2",
"pivot": [-9, 7.75, -0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [-10, 7.75, -1.75], "size": [1, 1, 1], "inflate": 0.25, "uv": [0, 21], "mirror": true}
{"origin": [-10, 7.75, -1.5], "size": [1, 1, 1], "uv": [36, 2]}
]
},
{
"name": "finger_right2",
"parent": "fingers_right",
"pivot": [-9, 7.75, 0.75],
"parent": "arm_right2",
"pivot": [-9, 7.75, 0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [-10, 7.75, 0.75], "size": [1, 1, 1], "inflate": 0.25, "uv": [12, 21], "mirror": true}
{"origin": [-10, 7.75, 0.5], "size": [1, 1, 1], "uv": [36, 0]}
]
},
{
"name": "finger_right3",
"parent": "fingers_right",
"pivot": [-9, 7.25, 0],
"parent": "arm_right2",
"pivot": [-9, 8, 0],
"cubes": [
{"origin": [-10, 6.25, -0.5], "size": [1, 1, 1], "inflate": 0.25, "uv": [16, 21], "mirror": true}
{"origin": [-10, 7, -0.5], "size": [1, 1, 1], "uv": [10, 32]}
]
},
{
"name": "arm_hammer_right",
"parent": "arms",
"pivot": [-2, 7.5, 0]
},
{
"name": "arm_hammer_right2",
"parent": "arm_hammer_right",
"pivot": [-5, 8.5, 1.5]
},
{
"name": "hammer",
"parent": "arm_hammer_right2",
"pivot": [-10, 7.5, 0]
},
{
"name": "hammer2",
"parent": "hammer",
"pivot": [-10.05, 7.5, -11.25],
"cubes": [
{"origin": [-11, 6.5, -11.85], "size": [2, 2, 16], "inflate": -0.1, "uv": [91, 18]}
]
},
{
"name": "ball",
"parent": "hammer2",
"pivot": [-10, 7.5, -14.75],
"cubes": [
{"origin": [-11.5, 6, -14.75], "size": [3, 3, 3], "uv": [94, 27]},
{"origin": [-11.5, 6, -14.75], "size": [3, 3, 3], "inflate": 0.1, "uv": [112, 27]}
]
},
{
"name": "rattle",
"parent": "hammer2",
"pivot": [-10, 7.5, -15.25],
"cubes": [
{"origin": [-11.5, 6, -22.75], "size": [3, 3, 6], "uv": [84, 37]},
{"origin": [-10.5, 7, -16.75], "size": [1, 1, 2], "uv": [97, 23]},
{"origin": [-10.5, 6, -21.25], "size": [1, 1, 1], "inflate": 0.02, "pivot": [-10, 6.5, -20.75], "rotation": [0, -45, 0], "uv": [97, 40]},
{"origin": [-11, 6, -20.25], "size": [2, 1, 2], "inflate": 0.02, "pivot": [-10, 6.5, -19.25], "rotation": [0, -45, 0], "uv": [81, 38]},
{"origin": [-11, 6, -20.75], "size": [2, 1, 2], "inflate": 0.01, "uv": [114, 23]}
]
},
{
"name": "locator_item",
"parent": "rattle",
"pivot": [-10, 5.3, -19],
"locators": {
"item": {
"offset": [-10, 5.3, -19],
"rotation": [0, 135, 0]
}
}
},
{
"name": "plates",
"parent": "hammer2",
"pivot": [-10, 9.025, -20.275]
},
{
"name": "plate_top",
"parent": "plates",
"pivot": [-3.5, 9.525, -20.275],
"cubes": [
{"origin": [-4, 4.5, -20.26], "size": [6, 8, 0], "pivot": [-4, 10, -20.25], "rotation": [-90, -180, 0], "uv": [115, 46]},
{"origin": [0, -1.5, -20.26], "size": [4, 8, 0], "pivot": [-2, 4, -20.25], "rotation": [-90, -180, 0], "uv": [117, 37]},
{"origin": [8, 4.5, -20.26], "size": [0, 8, 6], "pivot": [2, 10, -20.25], "rotation": [-90, -180, 0], "uv": [115, 49]}
]
},
{
"name": "plate_middle",
"parent": "plates",
"pivot": [-6.5, 9.525, -21.775],
"cubes": [
{"origin": [-10, 4.5, -21.75], "size": [8, 9, 0], "pivot": [-8, 10, -21.75], "rotation": [-90, -180, 0], "uv": [85, 47]},
{"origin": [-10, 4.5, -30.75], "size": [8, 0, 6], "pivot": [-8, 10, -30.75], "rotation": [-90, -180, 0], "uv": [79, 57]}
]
},
{
"name": "plate_bottom",
"parent": "plates",
"pivot": [-16.5, 10.525, -20.775],
"cubes": [
{"origin": [-21, 4.5, -20.74], "size": [5, 8, 0], "pivot": [-16, 10, -20.75], "rotation": [-90, 180, 0], "uv": [103, 46]},
{"origin": [-24, -1.5, -20.74], "size": [4, 8, 0], "pivot": [-18, 4, -20.75], "rotation": [-90, 180, 0], "uv": [104, 37], "mirror": true},
{"origin": [-28, 4.5, -20.74], "size": [0, 8, 6], "pivot": [-22, 10, -20.75], "rotation": [-90, 180, 0], "uv": [102, 49], "mirror": true}
]
},
{
"name": "locator_physical",
"parent": "plate_bottom",
"pivot": [-16, 7, -19],
"locators": {
"physical": [-16, 7, -19]
}
},
{
"name": "bandage",
"parent": "plates",
"pivot": [-8, 10, -22.25],
"cubes": [
{"origin": [-10.75, 10.2, -23.25], "size": [2, 0, 6], "pivot": [-9.75, 13, -20.25], "rotation": [0, 45, 0], "uv": [74, 57]},
{"origin": [-10.75, 10.1, -23.25], "size": [2, 0, 6], "pivot": [-9.75, 13, -20.25], "rotation": [0, -55, 0], "uv": [69, 57]}
]
},
{
"name": "skirt",
"name": "head",
"parent": "torso",
"pivot": [0, 3, 0]
},
{
"name": "skirt_left",
"parent": "skirt",
"pivot": [2.7, 3, -0.5],
"rotation": [0, 0, 30],
"pivot": [0, 9, 0.5],
"cubes": [
{"origin": [2.7, 3, -2], "size": [3, 0, 3], "uv": [65, 60]}
{"origin": [-3.5, 9, -3.5], "size": [7, 6, 7], "uv": [0, 19]},
{"origin": [-4, 17.30092, -3.63266], "size": [8, 0, 8], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [12, 0]},
{"origin": [4, 10.30092, -3.63266], "size": [0, 7, 8], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [20, 0]},
{"origin": [-4, 10.30092, 4.36734], "size": [8, 7, 0], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [0, 0]},
{"origin": [-4, 11.30092, -3.63266], "size": [8, 6, 0], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [42, 9]},
{"origin": [-4, 10.30092, -3.63266], "size": [0, 7, 8], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [0, 0]}
]
},
{
"name": "skirt_right",
"parent": "skirt",
"pivot": [-2.7, 3, -0.5],
"rotation": [0, 0, -30],
"name": "eye_left",
"parent": "head",
"pivot": [2.25, 12.25, -3.01],
"rotation": [0, 0, -7.5],
"cubes": [
{"origin": [-5.7, 3, -2], "size": [3, 0, 3], "uv": [65, 56], "mirror": true}
{"origin": [1.75, 11.25, -3.51], "size": [1, 2, 1], "uv": [21, 23]}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [-0.2, 4.5, 0]
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.25, 12.25, -2.91],
"cubes": [
{"origin": [1.75, 11.25, -3.41], "size": [1, 2, 1], "inflate": 0.01, "uv": [26, 15]}
]
},
{
"name": "eye_right",
"parent": "head",
"pivot": [-2.25, 12.25, -3.01],
"rotation": [0, 0, 7.5],
"cubes": [
{"origin": [-2.75, 11.25, -3.51], "size": [1, 2, 1], "uv": [0, 21]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.25, 12.25, -2.91],
"cubes": [
{"origin": [-2.75, 11.25, -3.41], "size": [1, 2, 1], "inflate": 0.01, "uv": [3, 23]}
]
},
{
"name": "mouth_open",
"parent": "head",
"pivot": [0, 10.5, -3.41],
"cubes": [
{"origin": [-1.5, 9.5, -3.41], "size": [3, 2, 0], "uv": [20, 15]}
]
},
{
"name": "mouth_closed",
"parent": "head",
"pivot": [0, 10.5, -3.51],
"cubes": [
{"origin": [-1.5, 9.5, -3.51], "size": [3, 2, 0], "uv": [0, 19]}
]
},
{
"name": "ponytail",
"parent": "head",
"pivot": [0, 16.81524, 1.82582],
"rotation": [2.5, 0, 0],
"cubes": [
{"origin": [-2, 16.62133, -0.28751], "size": [4, 4, 8], "uv": [20, 24]}
]
},
{
"name": "ponytail2",
"parent": "ponytail",
"pivot": [0, 16.62133, 3.71249],
"cubes": [
{"origin": [-2, 9.62133, 3.71249], "size": [4, 7, 4], "inflate": -0.001, "uv": [36, 19]}
]
},
{
"name": "ponytail3",
"parent": "ponytail2",
"pivot": [0, 11.62133, 7.71249],
"cubes": [
{"origin": [-2, 9.62133, 7.71249], "size": [4, 2, 3], "inflate": -0.002, "uv": [21, 45]}
]
},
{
"name": "hair2",
"parent": "head",
"pivot": [3.25, 16.625, -1.925],
"rotation": [-30, 0, 27.5]
},
{
"name": "hair3",
"parent": "hair2",
"pivot": [3.25, 16.625, -1.925],
"cubes": [
{"origin": [1.25, 16.625, -1.925], "size": [4, 6, 0], "uv": [48, 15]}
]
},
{
"name": "leg_left",
"parent": "legs",
"pivot": [1.55, 4, 0],
"parent": "body",
"pivot": [1.25, 4, 0],
"cubes": [
{"origin": [0.05, 1.5, -1.5], "size": [3, 3, 3], "inflate": -0.25, "uv": [12, 33]}
{"origin": [0.25, 2, -1], "size": [2, 2, 2], "uv": [28, 50]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [1.55, 1.7, -1.4],
"pivot": [1.25, 2, -1],
"cubes": [
{"origin": [0.05, 0, -1.5], "size": [3, 2, 3], "uv": [12, 39]}
{"origin": [0.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [50, 0]}
]
},
{
"name": "locator_foot_secondary",
"parent": "leg_left2",
"pivot": [1.6, 0.5, 0],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [1.6, 0.5, 0]
}
},
{
"name": "leg_right",
"parent": "legs",
"pivot": [-1.55, 4, 0],
"parent": "body",
"pivot": [-1.25, 4, 0],
"cubes": [
{"origin": [-3.05, 1.5, -1.5], "size": [3, 3, 3], "inflate": -0.25, "uv": [0, 33], "mirror": true}
{"origin": [-2.25, 2, -1], "size": [2, 2, 2], "uv": [20, 50]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-1.55, 1.7, -1.4],
"pivot": [-1.25, 2, -1],
"cubes": [
{"origin": [-3.05, 0, -1.5], "size": [3, 2, 3], "uv": [0, 39], "mirror": true}
{"origin": [-2.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [12, 32]}
]
},
{
"name": "locator_foot_primary",
"parent": "leg_right2",
"pivot": [-1.6, 0.5, 0],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-1.6, 0.5, 0]
}
}
]
}
@@ -0,0 +1,305 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.tinkatuff_dot",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "tinkatuff",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "tinkatuff",
"pivot": [0, 6, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 4.25, 0],
"cubes": [
{"origin": [-2, 7.5, -1.5], "size": [4, 3, 3], "uv": [41, 41]},
{"origin": [-2.5, 3, -2], "size": [5, 5, 4], "uv": [36, 0]}
]
},
{
"name": "skirt_left",
"parent": "torso",
"pivot": [2.5, 3, 0],
"rotation": [0, 0, 45],
"cubes": [
{"origin": [2.5, 3, -1.5], "size": [3, 0, 3], "uv": [6, 15]}
]
},
{
"name": "skirt_right",
"parent": "torso",
"pivot": [-2.5, 3, 0],
"rotation": [0, 0, -45],
"cubes": [
{"origin": [-5.5, 3, -1.5], "size": [3, 0, 3], "uv": [0, 15]}
]
},
{
"name": "arm_left",
"parent": "torso",
"pivot": [2, 8, 0],
"cubes": [
{"origin": [1, 7, -1], "size": [4, 2, 2], "uv": [35, 47]}
]
},
{
"name": "arm_left2",
"parent": "arm_left",
"pivot": [5, 9, 1],
"cubes": [
{"origin": [5, 7, -1.5], "size": [4, 2, 3], "inflate": 0.001, "uv": [44, 35]}
]
},
{
"name": "finger_left",
"parent": "arm_left2",
"pivot": [9, 7.75, -0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [9, 7.75, -1.5], "size": [1, 1, 1], "uv": [33, 44]}
]
},
{
"name": "finger_left2",
"parent": "arm_left2",
"pivot": [9, 7.75, 0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [9, 7.75, 0.5], "size": [1, 1, 1], "uv": [40, 30]}
]
},
{
"name": "finger_left3",
"parent": "arm_left2",
"pivot": [9, 8, 0],
"cubes": [
{"origin": [9, 7, -0.5], "size": [1, 1, 1], "uv": [36, 30]}
]
},
{
"name": "arm_hammer_right",
"parent": "torso",
"pivot": [-2, 8, 0]
},
{
"name": "arm_hammer_right2",
"parent": "arm_hammer_right",
"pivot": [-5, 9, 1]
},
{
"name": "hammer",
"parent": "arm_hammer_right2",
"pivot": [-9.75, 8, 0]
},
{
"name": "hammer2",
"parent": "hammer",
"pivot": [-9.55, 7.9675, -9.0675],
"cubes": [
{"origin": [-11, 6.5, -20], "size": [3, 3, 6], "uv": [30, 9]},
{"origin": [-10.5, 6.475, -18], "size": [2, 0, 2], "pivot": [-9.5, 6.475, -17], "rotation": [0, 45, 0], "uv": [-1, 54]},
{"origin": [-11, 6.5, -12.5], "size": [3, 3, 3], "uv": [0, 47]},
{"origin": [-10, 7.5, -14.5], "size": [1, 1, 18], "inflate": 0.001, "uv": [0, 0]},
{"origin": [-15.5, 4.025, -18.525], "size": [12, 11, 0], "pivot": [-9.5, 9.525, -18.525], "rotation": [-90, -180, 0], "uv": [0, 36]},
{"origin": [-15, 6.53, -18.04], "size": [7, 7, 0], "pivot": [-11, 9.53, -18.04], "rotation": [90, -45, -180], "uv": [42, 56]},
{"origin": [-15.5, 3.5, -30.5], "size": [0, 8, 5], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [34, 31]},
{"origin": [-15.5, 3.5, -30.5], "size": [3, 8, 0], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [47, 47]},
{"origin": [-7.5, 2.5, -30.5], "size": [4, 9, 0], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [12, 47]},
{"origin": [-3.5, 2.525, -20.025], "size": [0, 9, 5], "pivot": [-3.5, 7.025, -17.525], "rotation": [90, 180, 0], "uv": [24, 31]},
{"origin": [-13.5, 12.5, -29.5], "size": [8, 1, 0], "pivot": [-9.5, 12.25, -22.775], "rotation": [90, 0, 0], "uv": [0, 7]},
{"origin": [-13.5, 7.525, -26.025], "size": [8, 0, 4], "pivot": [-9.5, 7.525, -24.025], "rotation": [90, 180, 0], "uv": [17, 19]}
]
},
{
"name": "arm_right",
"parent": "torso",
"pivot": [-2, 8, 0],
"cubes": [
{"origin": [-5, 7, -1], "size": [4, 2, 2], "uv": [0, 32]}
]
},
{
"name": "arm_right2",
"parent": "arm_right",
"pivot": [-5, 9, 1],
"cubes": [
{"origin": [-9, 7, -1.5], "size": [4, 2, 3], "inflate": 0.001, "uv": [44, 30]}
]
},
{
"name": "finger_right",
"parent": "arm_right2",
"pivot": [-9, 7.75, -0.5],
"rotation": [0, -12.5, 0],
"cubes": [
{"origin": [-10, 7.75, -1.5], "size": [1, 1, 1], "uv": [36, 2]}
]
},
{
"name": "finger_right2",
"parent": "arm_right2",
"pivot": [-9, 7.75, 0.5],
"rotation": [0, 12.5, 0],
"cubes": [
{"origin": [-10, 7.75, 0.5], "size": [1, 1, 1], "uv": [36, 0]}
]
},
{
"name": "finger_right3",
"parent": "arm_right2",
"pivot": [-9, 8, 0],
"cubes": [
{"origin": [-10, 7, -0.5], "size": [1, 1, 1], "uv": [10, 32]}
]
},
{
"name": "head",
"parent": "torso",
"pivot": [0, 9, 0.5],
"cubes": [
{"origin": [-3.5, 9, -3.5], "size": [7, 6, 7], "uv": [0, 19]},
{"origin": [-4, 17.30092, -3.63266], "size": [8, 0, 8], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [12, 0]},
{"origin": [4, 10.30092, -3.63266], "size": [0, 7, 8], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [20, 0]},
{"origin": [-4, 10.30092, 4.36734], "size": [8, 7, 0], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [0, 0]},
{"origin": [-4, 11.30092, -3.63266], "size": [8, 6, 0], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [42, 9]},
{"origin": [-4, 10.30092, -3.63266], "size": [0, 7, 8], "pivot": [0, 13.80092, 0.36734], "rotation": [-7.5, 0, 0], "uv": [0, 0]}
]
},
{
"name": "eye_left",
"parent": "head",
"pivot": [2.25, 12.25, -3.01],
"rotation": [0, 0, -7.5],
"cubes": [
{"origin": [1.75, 11.25, -3.51], "size": [1, 2, 1], "uv": [21, 23]}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.25, 12.25, -2.91],
"cubes": [
{"origin": [1.75, 11.25, -3.41], "size": [1, 2, 1], "inflate": 0.01, "uv": [26, 15]}
]
},
{
"name": "eye_right",
"parent": "head",
"pivot": [-2.25, 12.25, -3.01],
"rotation": [0, 0, 7.5],
"cubes": [
{"origin": [-2.75, 11.25, -3.51], "size": [1, 2, 1], "uv": [0, 21]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.25, 12.25, -2.91],
"cubes": [
{"origin": [-2.75, 11.25, -3.41], "size": [1, 2, 1], "inflate": 0.01, "uv": [3, 23]}
]
},
{
"name": "mouth_open",
"parent": "head",
"pivot": [0, 10.5, -3.41],
"cubes": [
{"origin": [-1.5, 9.5, -3.41], "size": [3, 2, 0], "uv": [20, 15]}
]
},
{
"name": "mouth_closed",
"parent": "head",
"pivot": [0, 10.5, -3.51],
"cubes": [
{"origin": [-1.5, 9.5, -3.51], "size": [3, 2, 0], "uv": [0, 19]}
]
},
{
"name": "ponytail",
"parent": "head",
"pivot": [0, 16.81524, 1.82582],
"rotation": [2.5, 0, 0],
"cubes": [
{"origin": [-2, 16.62133, -0.28751], "size": [4, 4, 8], "uv": [20, 24]}
]
},
{
"name": "ponytail2",
"parent": "ponytail",
"pivot": [0, 16.62133, 3.71249],
"cubes": [
{"origin": [-2, 9.62133, 3.71249], "size": [4, 7, 4], "inflate": -0.001, "uv": [36, 19]}
]
},
{
"name": "ponytail3",
"parent": "ponytail2",
"pivot": [0, 11.62133, 7.71249],
"cubes": [
{"origin": [-2, 9.62133, 7.71249], "size": [4, 2, 3], "inflate": -0.002, "uv": [21, 45]}
]
},
{
"name": "hair2",
"parent": "head",
"pivot": [3.25, 16.625, -1.925],
"rotation": [-30, 0, 27.5]
},
{
"name": "hair3",
"parent": "hair2",
"pivot": [3.25, 16.625, -1.925],
"cubes": [
{"origin": [1.25, 16.625, -1.925], "size": [4, 6, 0], "uv": [48, 15]}
]
},
{
"name": "leg_left",
"parent": "body",
"pivot": [1.25, 4, 0],
"cubes": [
{"origin": [0.25, 2, -1], "size": [2, 2, 2], "uv": [28, 50]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [1.25, 2, -1],
"cubes": [
{"origin": [0.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [50, 0]}
]
},
{
"name": "leg_right",
"parent": "body",
"pivot": [-1.25, 4, 0],
"cubes": [
{"origin": [-2.25, 2, -1], "size": [2, 2, 2], "uv": [20, 50]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-1.25, 2, -1],
"cubes": [
{"origin": [-2.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [12, 32]}
]
}
]
}
]
}
@@ -0,0 +1,650 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.tinkaton_dot",
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 5,
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
},
"bones": [
{
"name": "bb_main",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-2, 0, 0], "size": [2, 2, 2], "uv": [0, 0]}
]
},
{
"name": "tinkaton",
"pivot": [0, 0, 0]
},
{
"name": "body_hammer",
"parent": "tinkaton",
"pivot": [0, 7, 0]
},
{
"name": "torso_hammer",
"parent": "body_hammer",
"pivot": [0, 4, 0]
},
{
"name": "arms_hammer",
"parent": "torso_hammer",
"pivot": [0, 7, 0]
},
{
"name": "arm_hammer_right",
"parent": "arms_hammer",
"pivot": [-1.5, 6.5, 0]
},
{
"name": "hand_hammer_right",
"parent": "arm_hammer_right",
"pivot": [-4.5, 6.5, 1.5]
},
{
"name": "hammer",
"parent": "hand_hammer_right",
"pivot": [-8, 5.125, -0.5]
},
{
"name": "hammer_handle",
"parent": "hammer",
"pivot": [-8, 5.375, -15.75],
"cubes": [
{"origin": [-8, 1.25, -23], "size": [0, 4, 4], "uv": [64, 48]},
{"origin": [-9.5, 5.25, -23], "size": [3, 4, 5], "inflate": -0.001, "uv": [87, 0]},
{"origin": [-9.5, 3.25, -19], "size": [3, 5, 4], "uv": [88, 34]},
{"origin": [-9, 4.25, -15], "size": [2, 2, 21], "uv": [0, 27]}
]
},
{
"name": "hammer_middle",
"parent": "hammer_handle",
"pivot": [-8.8, 5.25, -29],
"cubes": [
{"origin": [-14, 12.252, -35], "size": [12, 0, 12], "inflate": 0.001, "uv": [37, 27]},
{"origin": [-14, -0.752, -35], "size": [12, 0, 12], "inflate": 0.001, "uv": [13, 27]},
{"origin": [-14, -0.75, -35], "size": [12, 13, 0], "inflate": 0.001, "uv": [80, 60]},
{"origin": [-14, -0.75, -35], "size": [0, 13, 12], "inflate": 0.001, "uv": [24, 50]},
{"origin": [-14, -0.75, -23], "size": [12, 13, 0], "inflate": 0.001, "uv": [20, 75]},
{"origin": [-2, -0.75, -35], "size": [0, 13, 12], "inflate": 0.001, "uv": [0, 38]},
{"origin": [-8, -2.75, -46], "size": [0, 12, 11], "uv": [48, 51]},
{"origin": [-9.3375, 5.7875, -30.025], "size": [2, 0, 2], "pivot": [-8.3375, 5.7875, -29.025], "rotation": [0, -45, -90], "uv": [93, 14]},
{"origin": [-13, -0.75, -24], "size": [10, 13, 0], "uv": [68, 83]},
{"origin": [-13, -0.75, -34], "size": [0, 13, 10], "uv": [0, 53]},
{"origin": [-3, -0.75, -34], "size": [0, 13, 10], "uv": [0, 17]},
{"origin": [-13, -0.75, -34], "size": [10, 13, 0], "uv": [0, 76]},
{"origin": [-13, -0.75, -34], "size": [10, 0, 10], "uv": [47, 0]},
{"origin": [-13, 12.25, -34], "size": [10, 0, 10], "uv": [36, 39]},
{"origin": [-10.5, 0.75, -28], "size": [1, 8, 1], "pivot": [-10, 5.75, -27.5], "rotation": [90, 0, 0], "uv": [20, 63]},
{"origin": [-11.5, 2.75, -30.5], "size": [3, 6, 3], "pivot": [-10, 5.75, -29], "rotation": [90, 0, -90], "uv": [57, 10]}
]
},
{
"name": "hammer_front",
"parent": "hammer_middle",
"pivot": [-7.4, 12.3, -28.5],
"cubes": [
{"origin": [-12, 12.25, -33], "size": [8, 3, 8], "uv": [64, 41]},
{"origin": [-17.5, 15.25, -38.25], "size": [19, 8, 19], "uv": [0, 0]},
{"origin": [-17.5, 15.25, -40.25], "size": [0, 8, 2], "uv": [16, 38]},
{"origin": [-17.5, 15.25, -40.25], "size": [5, 0, 2], "uv": [0, 46]},
{"origin": [-17.5, 23.25, -40.25], "size": [5, 0, 2], "uv": [0, 17]},
{"origin": [-17.5, 15.25, -40.25], "size": [15, 8, 0], "uv": [73, 52]}
]
},
{
"name": "nail",
"parent": "hammer_front",
"pivot": [-5.5, 20.25, -38.25],
"rotation": [10, 0, 0],
"cubes": [
{"origin": [-6.5, 19.25, -42.25], "size": [2, 2, 5], "uv": [88, 73]},
{"origin": [-8, 17.75, -43.25], "size": [5, 5, 1], "uv": [24, 56]}
]
},
{
"name": "locator_hammer",
"parent": "hammer_front",
"pivot": [-8, 23, -28.75],
"rotation": [90, 0, 0],
"locators": {
"hammer": [-8, 23, -28.75],
"physical": [-8, 23, -28.75],
"special2": [-8, 23, -28.75]
}
},
{
"name": "hammer_back",
"parent": "hammer_middle",
"pivot": [-8, -1, -29],
"cubes": [
{"origin": [-11, -3.75, -32], "size": [6, 3, 6], "uv": [44, 77]},
{"origin": [-12.5, -7.75, -33.5], "size": [9, 4, 9], "uv": [37, 49]}
]
},
{
"name": "seat_1_locator",
"parent": "hammer_middle",
"pivot": [-8, 0, -35],
"rotation": [105, 0, 0],
"locators": {
"seat_1": [-8, 0, -35]
}
},
{
"name": "body",
"parent": "tinkaton",
"pivot": [0, 7, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 4, 0],
"cubes": [
{"origin": [-2, 6.5, -1.5], "size": [4, 3, 3], "inflate": 0.001, "uv": [88, 43]},
{"origin": [-2.5, 3, -2], "size": [5, 4, 4], "uv": [0, 0]}
]
},
{
"name": "skirt_front_right",
"parent": "torso",
"pivot": [-1.75, 3, -1.25],
"rotation": [30, 45, 0],
"cubes": [
{"origin": [-3.25, 3, -4.25], "size": [3, 0, 3], "uv": [37, 50]}
]
},
{
"name": "skirt_front_left",
"parent": "torso",
"pivot": [1.75, 3, -1.25],
"rotation": [30, -45, 0],
"cubes": [
{"origin": [0.25, 3, -4.25], "size": [3, 0, 3], "uv": [36, 45]}
]
},
{
"name": "skirt_back_left",
"parent": "torso",
"pivot": [1.75, 3, 1.25],
"rotation": [-30, 45, 0],
"cubes": [
{"origin": [0.25, 3, 1.25], "size": [3, 0, 3], "uv": [36, 42]}
]
},
{
"name": "skirt_back_right",
"parent": "torso",
"pivot": [-1.75, 3, 1.25],
"rotation": [-30, -45, 0],
"cubes": [
{"origin": [-3.25, 3, 1.25], "size": [3, 0, 3], "uv": [36, 39]}
]
},
{
"name": "head",
"parent": "torso",
"pivot": [0, 7.75, 0],
"cubes": [
{"origin": [-3.5, 7.75, -3.5], "size": [7, 7, 7], "uv": [73, 20]},
{"origin": [-3.5, 9.25, -4], "size": [0, 6, 8], "inflate": 0.01, "uv": [24, 42]},
{"origin": [3.5, 9.25, -4], "size": [0, 6, 8], "inflate": 0.01, "uv": [0, 32]},
{"origin": [-3.5, 8.25, 4], "size": [7, 7, 0], "inflate": 0.01, "uv": [88, 80]},
{"origin": [-3.5, 11.25, -4], "size": [7, 4, 0], "inflate": 0.01, "uv": [28, 88]},
{"origin": [-3.5, 15.25, -4], "size": [7, 0, 8], "inflate": 0.01, "uv": [17, 39]}
]
},
{
"name": "ear_left",
"parent": "head",
"pivot": [0, 14.75, 0],
"rotation": [0, 0, 10],
"cubes": [
{"origin": [0, 14.75, -1], "size": [3, 6, 2], "uv": [0, 89]}
]
},
{
"name": "ear_left2",
"parent": "head",
"pivot": [3, 14.75, 0],
"rotation": [0, 0, 20],
"cubes": [
{"origin": [3, 13.75, 0], "size": [2, 3, 0], "uv": [44, 78]}
]
},
{
"name": "ear_right",
"parent": "head",
"pivot": [0, 14.75, 0],
"rotation": [0, 0, -10],
"cubes": [
{"origin": [-3, 14.75, -1], "size": [3, 6, 2], "uv": [88, 87]}
]
},
{
"name": "ear_right2",
"parent": "head",
"pivot": [-3, 14.75, 0],
"cubes": [
{"origin": [-5, 13.75, 0], "size": [2, 3, 0], "pivot": [-3, 14.75, -0.5], "rotation": [0, 0, -20], "uv": [76, 22]}
]
},
{
"name": "eye_left",
"parent": "head",
"pivot": [2.5, 11.25, -3.025],
"cubes": [
{"origin": [2, 10.25, -3.525], "size": [1, 2, 1], "uv": [14, 0]}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [2.5, 11.25, -2.925],
"cubes": [
{"origin": [2, 10.25, -3.425], "size": [1, 2, 1], "inflate": 0.01, "uv": [76, 19]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [-2.5, 11.25, -3.5],
"locators": {
"eye1": [-2.5, 11.25, -3.5]
}
},
{
"name": "eye_right",
"parent": "head",
"pivot": [-2.5, 11.25, -3.025],
"cubes": [
{"origin": [-3, 10.25, -3.525], "size": [1, 2, 1], "uv": [0, 0]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-2.5, 11.25, -2.925],
"cubes": [
{"origin": [-3, 10.25, -3.425], "size": [1, 2, 1], "inflate": 0.01, "uv": [20, 72]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [2.5, 11.25, -3.5],
"locators": {
"eye2": [2.5, 11.25, -3.5]
}
},
{
"name": "mouths",
"parent": "head",
"pivot": [0, 9.25, -3.525]
},
{
"name": "mouth_open",
"parent": "mouths",
"pivot": [0, 9.25, -3.61],
"cubes": [
{"origin": [-2.5, 8.25, -3.41], "size": [5, 2, 0], "uv": [77, 0]}
]
},
{
"name": "locator_mouth",
"parent": "mouth_open",
"pivot": [0, 9.25, -3.5],
"locators": {
"mouth": [0, 9.25, -3.5]
}
},
{
"name": "mouth_closed",
"parent": "mouths",
"pivot": [0, 9.25, -3.41],
"cubes": [
{"origin": [-3.5, 8.25, -3.51], "size": [7, 2, 0], "uv": [48, 74]}
]
},
{
"name": "hair_right",
"parent": "head",
"pivot": [-3.5, 13.75, 0],
"cubes": [
{"origin": [-7, 9.75, -3], "size": [4, 5, 6], "uv": [14, 88]}
]
},
{
"name": "hair_right2",
"parent": "hair_right",
"pivot": [-3, 9.5, 0],
"cubes": [
{"origin": [-8, 0.75, -4], "size": [5, 9, 8], "uv": [69, 2]}
]
},
{
"name": "hair_right3",
"parent": "hair_right2",
"pivot": [-5.5, 0.75, 0],
"cubes": [
{"origin": [-5.5, -3.25, -4.5], "size": [0, 4, 9], "uv": [0, 4]}
]
},
{
"name": "hair_left",
"parent": "head",
"pivot": [3.5, 14.25, 0],
"cubes": [
{"origin": [3, 10.25, -3], "size": [4, 5, 6], "uv": [38, 86]}
]
},
{
"name": "hair_left2",
"parent": "hair_left",
"pivot": [3, 10, 0],
"cubes": [
{"origin": [3, 1.25, -4], "size": [5, 9, 8], "uv": [62, 66]}
]
},
{
"name": "hair_left3",
"parent": "hair_left2",
"pivot": [5.5, 1.25, 0],
"cubes": [
{"origin": [5.5, -2.75, -4.5], "size": [0, 4, 9], "uv": [0, 0]}
]
},
{
"name": "locator_head",
"parent": "head",
"pivot": [0, 15.25, -2.5],
"locators": {
"head": [0, 15.25, -2.5]
}
},
{
"name": "locator_item_hat",
"parent": "head",
"pivot": [0, 16.25, 0],
"locators": {
"item_hat": [0, 16.25, 0]
}
},
{
"name": "locator_tera_hat",
"parent": "head",
"pivot": [0, 15.25, 0],
"locators": {
"tera_hat": [0, 15.25, 0]
}
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 10.25, -3.5],
"locators": {
"face": [0, 10.25, -3.5]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 11.5, -3.5],
"locators": {
"item_face": [0, 11.5, -3.5]
}
},
{
"name": "arms",
"parent": "torso",
"pivot": [0, 7, 0]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [1.5, 6.5, 0],
"cubes": [
{"origin": [1.5, 5.5, -1.5], "size": [3, 2, 3], "uv": [94, 16]}
]
},
{
"name": "hand_left",
"parent": "arm_left",
"pivot": [4.5, 6.5, 1.5],
"cubes": [
{"origin": [4.5, 5.5, -2], "size": [4, 2, 4], "inflate": 0.01, "uv": [52, 86]}
]
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [7.75, 6.5, 0],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [7.75, 6.5, 0]
}
},
{
"name": "locator_item",
"parent": "hand_left",
"pivot": [9.5, 5.75, 0],
"locators": {
"item": [9.5, 5.75, 0]
}
},
{
"name": "finger_left",
"parent": "hand_left",
"pivot": [8.25, 7, -1.5],
"rotation": [0, 17.5, 0],
"cubes": [
{"origin": [8.25, 6, -2], "size": [2, 1, 1], "uv": [44, 76]}
]
},
{
"name": "finger_left2",
"parent": "hand_left",
"pivot": [8.5, 7, -0.5],
"rotation": [0, 5, 0],
"cubes": [
{"origin": [8.5, 6, -1], "size": [2, 1, 1], "uv": [73, 60]}
]
},
{
"name": "finger_left3",
"parent": "hand_left",
"pivot": [8.5, 7, 0.5],
"rotation": [0, -5, 0],
"cubes": [
{"origin": [8.5, 6, 0], "size": [2, 1, 1], "uv": [66, 47]}
]
},
{
"name": "finger_left4",
"parent": "hand_left",
"pivot": [8.25, 7, 1.5],
"rotation": [0, -17.5, 0],
"cubes": [
{"origin": [8.25, 6, 1], "size": [2, 1, 1], "uv": [66, 45]}
]
},
{
"name": "thumb_left",
"parent": "hand_left",
"pivot": [5, 5.5, -0.5],
"rotation": [0, 0, 42.5],
"cubes": [
{"origin": [5, 5.5, -1.5], "size": [2, 1, 2], "inflate": 0.01, "uv": [94, 24]}
]
},
{
"name": "arm_right",
"parent": "arms",
"pivot": [-1.5, 6.5, 0],
"cubes": [
{"origin": [-4.5, 5.5, -1.5], "size": [3, 2, 3], "uv": [58, 93]}
]
},
{
"name": "hand_right",
"parent": "arm_right",
"pivot": [-4.5, 6.5, 1.5],
"cubes": [
{"origin": [-8.5, 5.5, -2], "size": [4, 2, 4], "inflate": 0.01, "uv": [69, 35]}
]
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-7.75, 6.5, 0],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-7.75, 6.5, 0]
}
},
{
"name": "finger_right",
"parent": "hand_right",
"pivot": [-8.25, 7, -1.5],
"rotation": [0, -17.5, 0],
"cubes": [
{"origin": [-10.25, 6, -2], "size": [2, 1, 1], "uv": [66, 43]}
]
},
{
"name": "finger_right2",
"parent": "hand_right",
"pivot": [-8.5, 7, -0.5],
"rotation": [0, -5, 0],
"cubes": [
{"origin": [-10.5, 6, -1], "size": [2, 1, 1], "uv": [66, 41]}
]
},
{
"name": "finger_right3",
"parent": "hand_right",
"pivot": [-8.5, 7, 0.5],
"rotation": [0, 5, 0],
"cubes": [
{"origin": [-10.5, 6, 0], "size": [2, 1, 1], "uv": [64, 56]}
]
},
{
"name": "finger_right4",
"parent": "hand_right",
"pivot": [-8.25, 7, 1.5],
"rotation": [0, 17.5, 0],
"cubes": [
{"origin": [-10.25, 6, 1], "size": [2, 1, 1], "uv": [12, 17]}
]
},
{
"name": "thumb_right",
"parent": "hand_right",
"pivot": [-5, 5.5, -0.5],
"rotation": [0, 0, -42.5],
"cubes": [
{"origin": [-7, 5.5, -1.5], "size": [2, 1, 2], "inflate": 0.01, "uv": [94, 21]}
]
},
{
"name": "leg_right",
"parent": "body",
"pivot": [-1.25, 4, 0],
"cubes": [
{"origin": [-2.25, 2, -1], "size": [2, 2, 2], "uv": [10, 89]}
]
},
{
"name": "leg_right2",
"parent": "leg_right",
"pivot": [-1.25, 2, -1],
"cubes": [
{"origin": [-2.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [81, 34]}
]
},
{
"name": "locator_foot_primary",
"parent": "leg_right2",
"pivot": [-1.25, 0.5, 0],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-1.25, 0.5, 0]
}
},
{
"name": "leg_left",
"parent": "body",
"pivot": [1.25, 4, 0],
"cubes": [
{"origin": [0.25, 2, -1], "size": [2, 2, 2], "uv": [70, 62]}
]
},
{
"name": "leg_left2",
"parent": "leg_left",
"pivot": [1.25, 2, -1],
"cubes": [
{"origin": [0.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [38, 54]}
]
},
{
"name": "locator_foot_secondary",
"parent": "leg_left2",
"pivot": [1.25, 0.5, 0],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [1.25, 0.5, 0]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 7, 0],
"locators": {
"middle": [0, 7, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 7, -6],
"locators": {
"target": [0, 7, -6]
}
},
{
"name": "locator_root",
"parent": "tinkaton",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_special",
"parent": "tinkaton",
"pivot": [0, 7, -8],
"locators": {
"special": [0, 7, -8]
}
},
{
"name": "locator_top",
"parent": "tinkaton",
"pivot": [0, 23, 0],
"locators": {
"top": [0, 23, 0]
}
}
]
}
]
}
@@ -41,7 +41,7 @@
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"condition": "!q.in_air && !q.is_sprinting",
"condition": "!q.in_air && q.has_entity ? !q.is_sprinting : 1.0",
"animations": [
"q.bedrock('heracross', 'ground_walk')",
{
@@ -53,7 +53,7 @@
},
"running": {
"poseTypes": ["WALK", "SWIM"],
"condition": "!q.in_air && q.is_sprinting",
"condition": "!q.in_air && q.has_entity ? q.is_sprinting : 0.0",
"animations": [
"q.bedrock('heracross', 'ground_run')",
{
@@ -5,7 +5,8 @@
"profileTranslation": [0, 0.46, 0],
"rootBone": "mudkip",
"animations": {
"cry": "q.bedrock_stateful('mudkip', 'cry')"
"cry": "q.bedrock_stateful('mudkip', 'cry')",
"recoil": "q.bedrock_stateful('mudkip', 'recoil')"
},
"poses": {
"standing": {
@@ -5,7 +5,8 @@
"profileTranslation": [0, 0.65, 0],
"rootBone": "marshtomp",
"animations": {
"cry": "q.bedrock_stateful('marshtomp', 'cry')"
"cry": "q.bedrock_stateful('marshtomp', 'cry')",
"recoil": "q.bedrock_stateful('marshtomp', 'recoil')"
},
"poses": {
"standing": {
@@ -5,7 +5,8 @@
"profileTranslation": [0, 0.96, 0],
"rootBone": "swampert",
"animations": {
"cry": "q.bedrock_stateful('swampert', 'cry')"
"cry": "q.bedrock_stateful('swampert', 'cry')",
"recoil": "q.bedrock_stateful('swampert', 'recoil')"
},
"poses": {
"standing": {
@@ -1,8 +1,16 @@
{
"portraitScale": 2.48,
"portraitTranslation": [-0.33, -0.93, 0],
"portraitTranslation": [
-0.33,
-0.93,
0
],
"profileScale": 0.7,
"profileTranslation": [0.02, 0.76, 0],
"profileTranslation": [
0.02,
0.76,
0
],
"rootBone": "rufflet",
"animations": {
"cry": "q.bedrock_stateful('rufflet', 'cry')",
@@ -10,7 +18,13 @@
},
"poses": {
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"poseTypes": [
"STAND",
"NONE",
"PORTRAIT",
"PROFILE"
],
"isBattle": false,
"animations": [
"q.look('head')",
"q.bedrock('rufflet', 'ground_idle')"
@@ -22,7 +36,10 @@
]
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"poseTypes": [
"WALK",
"SWIM"
],
"animations": [
"q.look('head')",
"q.bedrock('rufflet', 'ground_walk')"
@@ -34,7 +51,9 @@
]
},
"hover": {
"poseTypes": ["HOVER"],
"poseTypes": [
"HOVER"
],
"animations": [
"q.pitch_tilt('body', 1)",
"q.look('head')",
@@ -46,7 +65,9 @@
]
},
"fly": {
"poseTypes": ["FLY"],
"poseTypes": [
"FLY"
],
"animations": [
"q.pitch_tilt('body', 1)",
"q.look('head')",
@@ -60,9 +81,6 @@
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
"animations": ["q.bedrock('rufflet', 'sleep')"],
"transformTicks": 10
}
@@ -22,6 +22,7 @@
"poses": {
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": [
"q.look('neck1', 1, 1, 5, -5, 10, -10)",
"q.look('neck2', 1, 1, 35, -10, 15, -15)",
@@ -95,9 +96,6 @@
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
"animations": ["q.bedrock('braviary', 'sleep')"],
"transformTicks": 10
}
@@ -22,6 +22,7 @@
"poses": {
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": [
"q.look('neck', 1, 1, 3, -20, 10, -10)",
"q.look('neck2', 1, 1, 1, -35, 15, -15)",
@@ -95,9 +96,6 @@
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
"animations": ["q.bedrock('braviary_hisuian', 'sleep')"],
"transformTicks": 10
}
@@ -19,9 +19,28 @@
"cry": "q.bedrock_stateful('mudsdale', 'cry')"
},
"poses": {
"standing": {
"poseName": "standing",
"poseTypes": ["STAND", "FLOAT", "NONE", "PORTRAIT", "PROFILE"],
"condition": "q.has_entity ? !q.in_air : 1.0",
"animations": [
"q.look('neck', 0.5, 0.5, 15, -15, 30, -30)",
"q.look('neck2', 0.5, 0.5, 10, -10, 25, -25)",
"q.look('head', 0.4, 0.25, 5, -5, 10, -10)",
"q.bedrock('mudsdale', 'ground_idle')",
"q.bedrock_stateful('mudsdale', 'blink')"
],
"transformTicks": 10
},
"sleep": {
"poseName": "sleep",
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('mudsdale', 'sleep')"]
},
"in-air": {
"poseTypes": ["STAND", "WALK"],
"condition": "q.in_air",
"isBattle": false,
"animations": [
"q.look('neck', 0.5, 0.5, 15, -15, 30, -30)",
"q.look('neck2', 0.5, 0.5, 10, -10, 25, -25)",
@@ -33,37 +52,10 @@
"transformTicks": 5,
"transformToTicks": 5
},
"standing": {
"poseTypes": ["STAND", "FLOAT", "NONE", "PORTRAIT", "PROFILE"],
"condition": "!q.in_air",
"animations": [
"q.look('neck', 0.5, 0.5, 15, -15, 30, -30)",
"q.look('neck2', 0.5, 0.5, 10, -10, 25, -25)",
"q.look('head', 0.4, 0.25, 5, -5, 10, -10)",
"q.bedrock('mudsdale', 'ground_idle')",
"q.bedrock_stateful('mudsdale', 'blink')"
],
"transformTicks": 5
},
"run": {
"poseTypes": ["WALK", "SWIM"],
"condition": "!q.in_air && q.is_sprinting",
"animations": [
"q.look('neck', 0.5, 0.5, 15, -15, 30, -30)",
"q.look('neck2', 0.5, 0.5, 10, -10, 25, -25)",
"q.look('head', 0.4, 0.25, 5, -5, 10, -10)",
"q.bedrock('mudsdale', 'ground_run')",
"q.bedrock_stateful('mudsdale', 'blink')",
{
"condition": "q.is_ridden && q.has_entity && !q.in_air",
"animation": "q.bedrock('mudsdale', 'ride_ground_run')"
}
],
"transformTicks": 5
},
"walk": {
"poseName": "walk",
"poseTypes": ["WALK", "SWIM"],
"condition": "!q.in_air && !q.is_sprinting",
"condition": "!q.is_sprinting",
"animations": [
"q.look('neck', 0.5, 0.5, 15, -15, 30, -30)",
"q.look('neck2', 0.5, 0.5, 10, -10, 25, -25)",
@@ -75,14 +67,23 @@
"animation": "q.bedrock('mudsdale', 'ride_ground_walk')"
}
],
"transformTicks": 5
"transformTicks": 10
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
"animations": ["q.bedrock('mudsdale', 'sleep')"]
"run": {
"poseTypes": ["WALK", "SWIM"],
"condition": "q.is_sprinting",
"animations": [
"q.look('neck', 0.5, 0.5, 15, -15, 30, -30)",
"q.look('neck2', 0.5, 0.5, 10, -10, 25, -25)",
"q.look('head', 0.4, 0.25, 5, -5, 10, -10)",
"q.bedrock('mudsdale', 'ground_run')",
"q.bedrock_stateful('mudsdale', 'blink')",
{
"condition": "q.is_ridden && q.has_entity && !q.in_air",
"animation": "q.bedrock('mudsdale', 'ride_ground_run')"
}
],
"transformTicks": 10
}
}
}
@@ -38,7 +38,7 @@
"q.bedrock_quirk('ceruledge', 'blink')"
],
"transitions": {
"battle-standing": "q.bedrock_primary('ceruledge', 'battle_intro', q.curve('one'))"
"battle-standing": "q.bedrock_primary('ceruledge', 'battle_intro')q.curve('symmetrical_wide'))"
}
},
"walking": {
@@ -1,66 +0,0 @@
{
"portraitScale": 2,
"portraitTranslation": [0, -1.01, 0.0],
"profileScale": 1,
"profileTranslation": [0.0, 0.25, 0.0],
"rootBone": "tinkatink",
"animations": {
"faint": "q.bedrock_primary('tinkatink', 'faint', q.curve('one'))",
"cry": "q.bedrock_stateful('tinkatink', 'cry')"
},
"poses": {
"battle-standing": {
"poseTypes": ["STAND"],
"isBattle": true,
"animations": [
"q.look('head')",
"q.bedrock('tinkatink', 'battle_idle')"
],
"quirks": ["q.bedrock_quirk('tinkatink', 'blink')"]
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": [
"q.look('head')",
"q.bedrock('tinkatink', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('tinkatink', 'blink')"]
},
"walking": {
"poseTypes": ["WALK"],
"animations": [
"q.look('head')",
"q.bedrock('tinkatink', 'ground_walk')"
],
"quirks": ["q.bedrock_quirk('tinkatink', 'blink')"]
},
"sleeping": {
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('tinkatink', 'sleep')"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
}
},
"shoulder_left": {
"poseTypes": ["SHOULDER_LEFT"],
"animations": [
"q.look('head')",
"q.bedrock('tinkatink', 'shoulder_left')"
],
"quirks": [
"q.bedrock_quirk('tinkatink', 'blink')"
]
},
"shoulder_right": {
"poseTypes": ["SHOULDER_RIGHT"],
"animations": [
"q.look('head')",
"q.bedrock('tinkatink', 'shoulder_right')"
],
"quirks": [
"q.bedrock_quirk('tinkatink', 'blink')"
]
}
}
}
@@ -1,46 +0,0 @@
{
"portraitScale": 1.9,
"portraitTranslation": [0, -0.41, 0.0],
"profileScale": 0.9,
"profileTranslation": [0.0, 0.4, 0.0],
"rootBone": "tinkatuff",
"animations": {
"faint": "q.bedrock_primary('tinkatuff', 'faint', q.curve('one'))",
"cry": "q.bedrock_stateful('tinkatuff', 'cry')"
},
"poses": {
"battle-standing": {
"poseTypes": ["STAND"],
"isBattle": true,
"animations": [
"q.look('head')",
"q.bedrock('tinkatuff', 'battle_idle')"
],
"quirks": ["q.bedrock_quirk('tinkatuff', 'blink')"]
},
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": [
"q.look('head')",
"q.bedrock('tinkatuff', 'ground_idle')"
],
"quirks": ["q.bedrock_quirk('tinkatuff', 'blink')"]
},
"walking": {
"poseTypes": ["WALK"],
"animations": [
"q.look('head')",
"q.bedrock('tinkatuff', 'ground_walk')"
],
"quirks": ["q.bedrock_quirk('tinkatuff', 'blink')"]
},
"sleeping": {
"poseTypes": ["SLEEP"],
"animations": ["q.bedrock('tinkatuff', 'sleep')"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
}
}
}
}
@@ -5,11 +5,6 @@
"profileTranslation": [0.0, 0.3, 0.0],
"rootBone": "tinkaton",
"animations": {
"physical": "q.bedrock_primary('tinkaton', 'physical', q.curve('symmetrical_wide'))",
"special": "q.bedrock_primary('tinkaton', 'special', q.curve('symmetrical_wide'))",
"status": "q.bedrock_primary('tinkaton', 'status', q.curve('symmetrical_wide'))",
"gigatonhammer": "q.bedrock_primary('tinkaton', 'signature', q.curve('symmetrical_wide'))",
"recoil": "q.bedrock_stateful('tinkaton', 'recoil')",
"faint": "q.bedrock_primary('tinkaton', 'faint', q.curve('one'))",
"cry": "q.bedrock_stateful('tinkaton', 'cry')"
},
@@ -18,65 +13,32 @@
"poseName": "battle-standing",
"poseTypes": ["STAND"],
"isBattle": true,
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'battle_idle')",
{
"condition": "q.is_wearing_hat",
"animation": "q.bedrock('tinkaton', 'hat')"
}
],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"namedAnimations": {
"cry": "q.bedrock_primary('tinkaton', 'battle_cry')"
}
"animations": ["q.look('head')", "q.bedrock('tinkaton', 'battle_idle')"],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"]
},
"standing": {
"poseName": "standing",
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
"isBattle": false,
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'ground_idle')",
{
"condition": "q.is_wearing_hat",
"animation": "q.bedrock('tinkaton', 'hat')"
}
],
"animations": ["q.look('head')", "q.bedrock('tinkaton', 'ground_idle')"],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition', q.curve('one'))"
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"walking": {
"poseName": "walking",
"poseTypes": ["WALK"],
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'ground_walk')",
{
"condition": "q.is_wearing_hat",
"animation": "q.bedrock('tinkaton', 'hat')"
}
],
"animations": ["q.look('head')", "q.bedrock('tinkaton', 'ground_walk')"],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition', q.curve('one'))"
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"sleeping": {
"poseName": "sleeping",
"poseTypes": ["SLEEP"],
"animations": [
"q.bedrock('tinkaton', 'sleep')",
{
"condition": "q.is_wearing_hat",
"animation": "q.bedrock('tinkaton', 'hat')"
}
],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
}
"animations": ["q.bedrock('tinkaton', 'sleep')"]
}
}
}
@@ -65,28 +65,6 @@
"animations": ["q.bedrock('gholdengo', 'sleep')"],
"quirks": []
},
"hover": {
"poseTypes": ["HOVER"],
"isTouchingWater": false,
"animations": [
"q.look('head')",
"q.bedrock('gholdengo', 'surfacewater_idle')"
],
"quirks": [
"q.bedrock_quirk('gholdengo', 'blink')"
]
},
"fly": {
"poseTypes": ["FLY"],
"isTouchingWater": false,
"animations": [
"q.look('head')",
"q.bedrock('gholdengo', 'surfacewater_swim')"
],
"quirks": [
"q.bedrock_quirk('gholdengo', 'blink')"
]
},
"surfacewater-standing": {
"poseTypes": ["STAND", "FLOAT"],
"isTouchingWater": true,
@@ -5,10 +5,6 @@
{
"aspects": ["female"],
"model": "cobblemon:combee_female.geo"
},
{
"aspects": ["shiny", "female"],
"texture": "cobblemon:textures/pokemon/0415_combee/combee_shiny.png"
}
]
}
@@ -15,10 +15,12 @@
},
{
"aspects": ["cosmetic_item-music"],
"model": "cobblemon:tinkatink_dot.geo",
"texture": "cobblemon:textures/pokemon/0957_tinkatink/tinkatink_dot.png"
},
{
"aspects": ["cosmetic_item-music", "shiny"],
"model": "cobblemon:tinkatink_dot.geo",
"texture": "cobblemon:textures/pokemon/0957_tinkatink/tinkatink_dot_shiny.png"
}
]
@@ -15,10 +15,12 @@
},
{
"aspects": ["cosmetic_item-music"],
"model": "cobblemon:tinkatuff_dot.geo",
"texture": "cobblemon:textures/pokemon/0958_tinkatuff/tinkatuff_dot.png"
},
{
"aspects": ["cosmetic_item-music", "shiny"],
"model": "cobblemon:tinkatuff_dot.geo",
"texture": "cobblemon:textures/pokemon/0958_tinkatuff/tinkatuff_dot_shiny.png"
}
]
@@ -15,10 +15,12 @@
},
{
"aspects": ["cosmetic_item-music"],
"model": "cobblemon:tinkaton_dot.geo",
"texture": "cobblemon:textures/pokemon/0959_tinkaton/tinkaton_dot.png"
},
{
"aspects": ["cosmetic_item-music", "shiny"],
"model": "cobblemon:tinkaton_dot.geo",
"texture": "cobblemon:textures/pokemon/0959_tinkaton/tinkaton_dot_shiny.png"
}
]
@@ -3847,9 +3847,6 @@
"cobblemon.behaviour.attack_hostile_mobs.name": "Attacks Hostile Mobs",
"cobblemon.behaviour.attack_hostile_mobs.desc": "Attacks hostile mobs that are nearby, even if unprovoked.",
"cobblemon.behaviour.defend_owner.name": "Defend Owner",
"cobblemon.behaviour.defend_owner.desc": "Defends its owner when they are attacked.",
"cobblemon.behaviour.pokemon_bee.name": "Pollinates Flowers",
"cobblemon.behaviour.pokemon_bee.desc": "Pollinates flowers and adds honey to hives and Saccharine tree leaves.",
Loaded 100 of 221 files, more files were not shown because too many files have changed in this diff. Show more